package l1j.server.server.model.Instance;

import static l1j.server.server.model.skill.L1SkillId.BLIND_HIDING;
import static l1j.server.server.model.skill.L1SkillId.BLOODLUST;
import static l1j.server.server.model.skill.L1SkillId.COUNTER_BARRIER;
import static l1j.server.server.model.skill.L1SkillId.DECREASE_WEIGHT;
import static l1j.server.server.model.skill.L1SkillId.DRESS_EVASION;
import static l1j.server.server.model.skill.L1SkillId.ENTANGLE;
import static l1j.server.server.model.skill.L1SkillId.FOG_OF_SLEEPING;
import static l1j.server.server.model.skill.L1SkillId.GMSTATUS_FINDINVIS;
import static l1j.server.server.model.skill.L1SkillId.GMSTATUS_HPBAR;
import static l1j.server.server.model.skill.L1SkillId.GREATER_HASTE;
import static l1j.server.server.model.skill.L1SkillId.HASTE;
import static l1j.server.server.model.skill.L1SkillId.HOLY_WALK;
import static l1j.server.server.model.skill.L1SkillId.ILLUSION_AVATAR;
import static l1j.server.server.model.skill.L1SkillId.INVISIBILITY;
import static l1j.server.server.model.skill.L1SkillId.JOY_OF_PAIN;
import static l1j.server.server.model.skill.L1SkillId.MASS_SLOW;
import static l1j.server.server.model.skill.L1SkillId.MORTAL_BODY;
import static l1j.server.server.model.skill.L1SkillId.MOVING_ACCELERATION;
import static l1j.server.server.model.skill.L1SkillId.STATUS_THIRD_SPEED;//TODO 三段加速
import static l1j.server.server.model.skill.L1SkillId.SLOW;
import static l1j.server.server.model.skill.L1SkillId.SOLID_CARRIAGE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_BRAVE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_CHAT_PROHIBITED;
import static l1j.server.server.model.skill.L1SkillId.STATUS_ELFBRAVE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_HASTE;
import static l1j.server.server.model.skill.L1SkillId.STATUS_RIBRAVE;
import static l1j.server.server.model.skill.L1SkillId.STRIKER_GALE;
import static l1j.server.server.model.skill.L1SkillId.WIND_WALK;
import static l1j.server.server.model.skill.L1SkillId.PC_IsPinkName;
import static l1j.server.server.model.skill.L1SkillId.WIND_SHACKLE;
import static l1j.server.server.model.skill.L1SkillId.ADDITIONAL_FIRE;
import static l1j.server.server.model.skill.L1SkillId.EXOTIC_VITALIZE;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.concurrent.ScheduledFuture;
import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.opqlo.NewSystem.刮刮樂;
import l1j.opqlo.NewSystem.各項記錄輸出;
import l1j.opqlo.NewSystem.Attack.L1AttackModel;
import l1j.opqlo.NewSystem.Attack.L1AttackPc;
import l1j.opqlo.Server.PcDeath;
import l1j.opqlo.Server.L1World.L1World;
import l1j.opqlo.Server.L1World.WorldClan;
import l1j.opqlo.Server.L1World.WorldWar;
import l1j.opqlo.Timer.Controler.Server.ServerWarExecutor;
import l1j.opqlo.掛機.RobotTemp;
import l1j.server.Config;
import l1j.server.GameServer.GameServer;
import l1j.server.Thread.GeneralThreadPool;
import l1j.server.echo.ClientThread;
import l1j.server.echo.EncryptExecutor;
import l1j.server.server.ActionCodes;
import l1j.server.server.clientpackets.AcceleratorChecker;
import l1j.server.server.datatables.CharBuffTable;
import l1j.server.server.datatables.CharacterTable;
import l1j.server.server.datatables.ExpTable;
import l1j.server.server.datatables.ItemTable;
import l1j.server.server.datatables.lock.GameConfigReading;
import l1j.server.server.datatables.lock.HellTimeReading;
import l1j.server.server.model.L1CastleLocation;
import l1j.server.server.model.L1Character;
import l1j.server.server.model.L1ChatParty;
import l1j.server.server.model.L1Clan;
import l1j.server.server.model.L1DollList;
import l1j.server.server.model.L1DwarfForElfInventory;
import l1j.server.server.model.L1DwarfInventory;
import l1j.server.server.model.L1EquipmentSlot;
import l1j.server.server.model.L1ExcludingList;
import l1j.server.server.model.L1Karma;
import l1j.server.server.model.L1Location;
import l1j.server.server.model.L1Magic;
import l1j.server.server.model.L1Object;
import l1j.server.server.model.L1Party;
import l1j.server.server.model.L1PartyRefresh;
import l1j.server.server.model.L1PcInventory;
import l1j.server.server.model.L1PinkName;
import l1j.server.server.model.L1Quest;
import l1j.server.server.model.L1Teleport;
import l1j.server.server.model.L1TownLocation;
import l1j.server.server.model.L1War;
import l1j.server.server.model.MpReductionByAwake;
import l1j.server.server.model.MpRegenerationByDoll;
import l1j.server.server.model.classes.L1ClassFeature;
import l1j.server.server.model.gametime.L1GameTimeCarrier;
import l1j.server.server.model.monitor.L1PcGhostMonitor;
import l1j.server.server.model.monitor.L1PcInvisDelay;
import l1j.server.server.model.skill.L1SkillId;
import l1j.server.server.model.skill.L1SkillUse;
import l1j.server.server.serverpackets.S_BlueMessage;
import l1j.server.server.serverpackets.S_CastleMaster;
import l1j.server.server.serverpackets.S_DoActionGFX;
import l1j.server.server.serverpackets.S_DoActionShop;
import l1j.server.server.serverpackets.S_Exp;
import l1j.server.server.serverpackets.S_Fight;
import l1j.server.server.serverpackets.S_HPMeter;
import l1j.server.server.serverpackets.S_HPUpdate;
import l1j.server.server.serverpackets.S_Invis;
import l1j.server.server.serverpackets.S_Karma;
import l1j.server.server.serverpackets.S_Lawful;
import l1j.server.server.serverpackets.S_MPUpdate;
import l1j.server.server.serverpackets.S_OtherCharPacks;
import l1j.server.server.serverpackets.S_OwnCharStatus;
import l1j.server.server.serverpackets.S_Paralysis;
import l1j.server.server.serverpackets.S_PinkName;
import l1j.server.server.serverpackets.S_Poison;
import l1j.server.server.serverpackets.S_RemoveObject;
import l1j.server.server.serverpackets.S_ServerMessage;
import l1j.server.server.serverpackets.S_SkillIconGFX;
import l1j.server.server.serverpackets.S_SystemMessage;
import l1j.server.server.serverpackets.S_bonusstats;
import l1j.server.server.serverpackets.ServerBasePacket;
import l1j.server.server.templates.GameConfig;
import l1j.server.server.templates.L1BookMark;
import l1j.server.server.templates.L1ChatTemp;
import l1j.server.server.templates.L1Item;
import l1j.server.server.templates.L1PrivateShopBuyList;
import l1j.server.server.templates.L1PrivateShopSellList;
import l1j.server.server.model.HpRegenerationByDoll;//TODO 魔法娃娃回血功能 by hot183
import l1j.server.server.model.ItemMakeByDoll;//TODO 魔法娃娃DB化

import java.text.SimpleDateFormat;//TODO 角色誕生by99團隊

import l1j.server.server.utils.CalcStat;
import l1j.server.server.utils.IntRange;
import l1j.server.server.utils.ListMapUtil;
import l1j.server.server.utils.Random;
import l1j.server.server.utils.collections.Lists;
import l1j.william.Reward;

public class L1PcInstance extends L1Character {
	private static final long serialVersionUID = 1L;
 
	public static final int CLASSID_KNIGHT_MALE = 61;
	public static final int CLASSID_KNIGHT_FEMALE = 48;
	public static final int CLASSID_ELF_MALE = 138;
	public static final int CLASSID_ELF_FEMALE = 37;
	public static final int CLASSID_WIZARD_MALE = 734;
	public static final int CLASSID_WIZARD_FEMALE = 1186;
	public static final int CLASSID_DARK_ELF_MALE = 2786;
	public static final int CLASSID_DARK_ELF_FEMALE = 2796;
	public static final int CLASSID_PRINCE = 0;
	public static final int CLASSID_PRINCESS = 1;
	public static final int CLASSID_DRAGON_KNIGHT_MALE = 6658;
	public static final int CLASSID_DRAGON_KNIGHT_FEMALE = 6661;
	public static final int CLASSID_ILLUSIONIST_MALE = 6671;
	public static final int CLASSID_ILLUSIONIST_FEMALE = 6650;

	private short _hpr = 0;
	private short _trueHpr = 0;

	/** 3.3C組隊系統 */
	boolean _rpActive = false;

	private int _partyType;

	// TODO 魔法娃娃DB化直接加給玩家的HPR效果
	public short getHpr() {
		return (short) (_hpr + _dollList.getHpr());
	}

	// TODO 魔法娃娃DB化直接加給玩家的HPR效果

	public void addHpr(int i) {
		_trueHpr += i;
		_hpr = (short) Math.max(0, _trueHpr);
	}

	private short _mpr = 0;
	private short _trueMpr = 0;

	// TODO 魔法娃娃DB化直接加給玩家的MPR效果
	public short getMpr() {
		return (short) (_mpr + _dollList.getMpr());
		// TODO 魔法娃娃DB化直接加給玩家的MPR效果
	}

	public void addMpr(int i) {
		_trueMpr += i;
		_mpr = (short) Math.max(0, _trueMpr);
	}

	public short _originalHpr = 0; // ● オリジナルCON HPR

	public short getOriginalHpr() {

		return _originalHpr;
	}

	public short _originalMpr = 0; // ● オリジナルWIS MPR

	public short getOriginalMpr() {

		return _originalMpr;
	}

	public static final int REGENSTATE_NONE = 4;
	public static final int REGENSTATE_MOVE = 2;
	public static final int REGENSTATE_ATTACK = 1;

	public void setRegenState(final int state) {
		this._mpRegenState = state;
		this._hpRegenState = state;
	}

	private static final int lvlTable[] = new int[] { 30, 25, 20, 16, 14, 12,
		11, 10, 9, 3, 2 };

	private int regenMax() {
		int regenLvl = Math.min(10, getLevel());
		if ((30 <= getLevel()) && isKnight()) {
			regenLvl = 11;
		}
		return lvlTable[regenLvl - 1] << 2;
	}

	private int _hpRegenType = 0;
	private int _hpRegenState = 4;

	public int getHpRegenState() {
		return this._hpRegenState;
	}

	public void set_hpRegenType(final int hpRegenType) {
		this._hpRegenType = hpRegenType;
	}

	public int hpRegenType() {
		return this._hpRegenType;
	}

	/**
	 * HP回復成立
	 * 
	 * @return
	 */
	public boolean isRegenHp() {
		if (!_hpRegenActive) {
			return false;
		}
		if (hasSkillEffect(EXOTIC_VITALIZE) || hasSkillEffect(ADDITIONAL_FIRE)) {
			return _hpRegenType >= regenMax();
		}
		if (120 <= _inventory.getWeight240()) {
			return false;
		}
		if ((_food < 3)) {
			return false;
		}
		return _hpRegenType >= regenMax();
	}

	private int _mpRegenType = 0;
	private int _mpRegenState = 4;

	public int getMpRegenState() {
		return this._mpRegenState;
	}

	public void set_mpRegenType(final int hpmpRegenType) {
		this._mpRegenType = hpmpRegenType;
	}

	public int mpRegenType() {
		return this._mpRegenType;
	}

	/**
	 * MP回復成立
	 * 
	 * @return
	 */
	public boolean isRegenMp() {
		if (!this._mpRegenActive) {
			return false;
		}
		if (this.hasSkillEffect(EXOTIC_VITALIZE)
				|| this.hasSkillEffect(ADDITIONAL_FIRE)) {
			return this._mpRegenType >= 64;
		}
		if (120 <= this._inventory.getWeight240()) {
			return false;
		}
		if ((this._food < 3)) {
			return false;
		}
		// 法師加速
		if (this.isWizard()) {
			return this._mpRegenType >= 40;
		}
		return this._mpRegenType >= 64;
	}

	/**
	 * HP自然回復啟用
	 */
	public void startHpRegeneration() {
		if (!_hpRegenActive) {
			_hpRegenActive = true;
		}
	}

	/**
	 * HP自然回復停止
	 */
	public void stopHpRegeneration() {
		if (_hpRegenActive) {
			_hpRegenActive = false;
		}
	}

	/**
	 * HP自然回復狀態
	 * 
	 * @return
	 */
	public boolean getHpRegenActive() {
		return _hpRegenActive;
	}

	/**
	 * MP自然回復啟用
	 */
	public void startMpRegeneration() {
		if (!_mpRegenActive) {
			_mpRegenActive = true;
		}
	}

	/**
	 * MP自然回復停止
	 */
	public void stopMpRegeneration() {
		if (_mpRegenActive) {
			_mpRegenActive = false;
		}
	}

	/**
	 * MP自然回復狀態
	 * 
	 * @return
	 */
	public boolean getMpRegenActive() {
		return _mpRegenActive;
	}

	// TODO 魔法娃娃物品製作開始
	public void startItemMakeByDoll(final int time , final int itemId) {
		boolean isExistItemMakeDoll = false;
		if (itemId > 0) {
			isExistItemMakeDoll = true;
		}
		// if (!_ItemMakeActiveByDoll && isExistItemMakeDoll) {
		if (isExistItemMakeDoll) {
			if (_itemMakeByDoll == null) {
				_itemMakeByDoll = new HashMap<Integer, ItemMakeByDoll>();
			}
			if (_itemMakeByDoll.get(itemId) != null) {
				_itemMakeByDoll.get(itemId).cancel();
				_itemMakeByDoll.remove(itemId);
			}
			final ItemMakeByDoll Make = new ItemMakeByDoll(this, itemId);
			_itemMakeByDoll.put(itemId, Make);
			int INTERVAL_BY_DOLL = (time * 1000);
			if (INTERVAL_BY_DOLL == 0) {
				INTERVAL_BY_DOLL = 240000;
			}
			_regenTimer.scheduleAtFixedRate(Make, INTERVAL_BY_DOLL,INTERVAL_BY_DOLL);
			// _ItemMakeActiveByDoll = true;
		}
	}

	// TODO 魔法娃娃物品製作停止
	public void stopItemMakeByDoll(final int itemId) {
		if (_itemMakeByDoll.get(itemId) != null) {
			_itemMakeByDoll.get(itemId).cancel();
			_itemMakeByDoll.remove(itemId);
			// if (_ItemMakeActiveByDoll) {
			// _itemMakeByDoll.cancel();
			// _itemMakeByDoll = null;
			// _ItemMakeActiveByDoll = false;
		}
	}


	public boolean isHpRegenByDoll(){
		return _hpRegenActiveByDoll;
	}
	private static Timer _regenTimer = new Timer(true);
	private static final int INTERVAL_BY_DOLL = 1000;
	// TODO 魔法娃娃　HPR開始
	public void startHpRegenerationByDoll() {
		// TODO 魔法娃娃額外回血功能改寫DB控制秒數定義
		boolean isExistHprDoll = false;
		if (_dollList.hasTimeHprByDoll()) {
			isExistHprDoll = true;
		}
		// TODO 魔法娃娃額外回血功能改寫DB控制秒數定義
		if (!_hpRegenActiveByDoll && isExistHprDoll) {
			_hpRegenByDoll = new HpRegenerationByDoll(this);
			_regenTimer.scheduleAtFixedRate(_hpRegenByDoll, INTERVAL_BY_DOLL,INTERVAL_BY_DOLL);
			_hpRegenActiveByDoll = true;
		}
	}

	// TODO 魔法娃娃　HPR停止
	public void stopHpRegenerationByDoll() {
		if (_hpRegenActiveByDoll) {
			_hpRegenByDoll.cancel();
			_hpRegenByDoll = null;
			_hpRegenActiveByDoll = false;
		}
	}
	
	// TODO 魔法娃娃　MPR開始
	public void startMpRegenerationByDoll() {

		// TODO 魔法娃娃額外回魔功能改寫DB控制秒數定義
		boolean isExistMprDoll = false;
		if (_dollList.hasTimeMprByDoll()) {
			isExistMprDoll = true;
		}
		// TODO 魔法娃娃額外回魔功能改寫DB控制秒數定義
		if (!_mpRegenActiveByDoll && isExistMprDoll) {
			_mpRegenByDoll = new MpRegenerationByDoll(this);
			_regenTimer.scheduleAtFixedRate(_mpRegenByDoll, INTERVAL_BY_DOLL,INTERVAL_BY_DOLL);
			_mpRegenActiveByDoll = true;
		}
	}

	// TODO 魔法娃娃　MPR停止
	public void stopMpRegenerationByDoll() {
		if (_mpRegenActiveByDoll) {
			if(_mpRegenByDoll !=null){
				_mpRegenByDoll.cancel();
				_mpRegenByDoll = null;
			}
			_mpRegenActiveByDoll = false;
		}
	}

	public void startMpReductionByAwake() {
		final int INTERVAL_BY_AWAKE = 4000;
		if (!_mpReductionActiveByAwake) {
			_mpReductionByAwake = new MpReductionByAwake(this);
			_regenTimer.scheduleAtFixedRate(_mpReductionByAwake,INTERVAL_BY_AWAKE, INTERVAL_BY_AWAKE);
			_mpReductionActiveByAwake = true;
		}
	}

	public void stopMpReductionByAwake() {
		if (_mpReductionActiveByAwake) {
			_mpReductionByAwake.cancel();
			_mpReductionByAwake = null;
			_mpReductionActiveByAwake = false;
		}
	}

	// TODO 魔法娃娃DB化
//	private static final long INTERVAL_EXP_MONITOR = 500;

//	private static final long INTERVAL_AUTO_UPDATE = 300;

	//	private ScheduledFuture<?> _pcDeleteTimer;

	/**自動更新計時器*/
//	private ScheduledFuture<?> _autoUpdateFuture;
	/**經驗更新計時器**/
//	private ScheduledFuture<?> _expMonitorFuture;

	/**鬼魂模式計時器*/
	private ScheduledFuture<?> _ghostFuture;

	//	public void startPcDeleteTimer(){
	//		_pcDeleteTimer =  PcOtherThreadPool.get().pcSchedule(new L1PcDeleteTimer(getId()), 180000);
	//	}

	/**
	 * <FONT COLOR="#0000ff">復活移出死亡清單</FONT>
	 */
	public void stopPcDeleteTimer() {
		this._isTeleport = false;
		this.setDead(false);
		// 加入死亡清單
		set_delete_time(0);
	}

	/**
	 * PC 可見物更新處理清單
	 */
	public void startObjectAutoUpdate() {
		removeAllKnownObjects();
//		_autoUpdateFuture = GeneralThreadPool.getInstance().pcScheduleAtFixedRate(new L1PcAutoUpdate(getId()), 0L, INTERVAL_AUTO_UPDATE);
	}
	/**開始經驗值更新*/
	public void beginExpMonitor() {
//		_expMonitorFuture = GeneralThreadPool.getInstance().pcScheduleAtFixedRate(new L1PcExpMonitor(getId()), 0L, INTERVAL_EXP_MONITOR);
	}

	//	private ScheduledFuture<?> _hellFuture;
	//		private HashMap<Integer , Integer>_killerList;
	//
	//		/**加入殺人清單**/
	//		public void addKillList(final int tragetId){
	//			if(_killerList == null){
	//				_killerList = L1World.getInstance().getKillList(getId());
	//			}
	//			 int killCount = 1;
	//			if(_killerList.containsKey(tragetId)){
	//				 killCount += _killerList.get(tragetId);
	//			}
	//			_killerList.put(tragetId, killCount);
	//		}
	//		
	//		public void clearKillList(){
	//			if(_killerList == null){
	//				return;
	//			}
	//			_killerList.clear();
	//		}

	private boolean _isInHell;
	public boolean isInHell(){
		return _isInHell;
	}

	private int _lastKillerId;
	/**寫入殺手ID*/
	public void setLastKillerId(final int attaekerId){
		_lastKillerId = attaekerId;
	}
	/**取得殺手ID*/
	public int getLastKillerId(){
		return _lastKillerId;
	}
	/**清除殺手ID*/
	public void removeKillerId(){
		_lastKillerId = 0;
		L1World.getInstance().removeKillerId(this.getId());
	}

	public void beginHell() {
		_isInHell = true;
		L1Teleport.teleportByMagic(this, 32788, 32795, (short)1784, 5, false);
		if(getHellTime()<=0){
			L1World.getInstance().removeKillerIdForChangeName(this.getId());
			final int pkcount = get_PKcount();
			final int time = Math.max(60, pkcount * 1800);
			setHellTime(time);
			HellTimeReading.get().BeginHell(this.getId(), time);
			this.set_PKcount(0);
			this.setLastPk(null);
			sendPackets(new S_BlueMessage(552, String.valueOf(pkcount),String.valueOf(getHellTime()/60)));
			try {
				this.save();
			} catch (Exception e) {
				_log.log(Level.SEVERE, e.getLocalizedMessage() , e);
			}
		}else{
			final int time = getHellTime();
			HellTimeReading.get().BeginHell(this.getId(), time);
			sendPackets(new S_BlueMessage(637, String.valueOf(time)));
		}
	}

	//	public void beginHell(final boolean isFirst) {
	//		_isInHell = true;
	//		if (isFirst) {
	//			//			if (get_PKcount() <= 10) {
	//			//				setHellTime(300);
	//			//			} else {
	//			//				setHellTime(300 * (get_PKcount() - 10) + 300);
	//			//			}
	//			final int pkcount = _killerList.size();
	//			if(pkcount <=21){
	//				setHellTime(600);
	//			}else{
	//				setHellTime(1800 * (pkcount -21) +600);
	//			}
	//			// あなたのPK回数が%0になり、地獄に落とされました。あなたはここで%1分間反省しなければなりません。
	//			sendPackets(new S_BlueMessage(552, String.valueOf(pkcount),String.valueOf(getHellTime() / 60)));
	//		} else {
	//			// あなたは%0秒間ここにとどまらなければなりません。
	//			sendPackets(new S_BlueMessage(637, String.valueOf(getHellTime())));
	//		}
	//		//		if (_hellFuture == null) {
	//		//			_hellFuture = GeneralThreadPool.getInstance().pcScheduleAtFixedRate(new L1PcHellMonitor(getId()), 0L,1000L);
	//		//		}
	//	}

	public void endHell() {
		//		if (_hellFuture != null) {
		//			_hellFuture.cancel(false);
		//			_hellFuture = null;
		//		}
		_isInHell = false;
		// 地獄から脱出したら火田村へ帰還させる。
		final int[] loc = L1TownLocation.getGetBackLoc(L1TownLocation.TOWNID_ORCISH_FOREST);
		L1Teleport.teleportByMagic(this, loc[0], loc[1], (short) loc[2], 5, true);
		try {
			save();
		} catch (Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage() , e);
		}
	}
	/**
	 * 移出各種處理清單
	 */
	public void stopEtcMonitor() {
		// 移出PC 鬼魂模式處理清單
//		if (_autoUpdateFuture != null) {
//			_autoUpdateFuture.cancel(true);
//			_autoUpdateFuture = null;
//		}
//		if (_expMonitorFuture != null) {
//			_expMonitorFuture.cancel(true);
//			_expMonitorFuture = null;
//		}
		if (_ghostFuture != null) {
			_ghostFuture.cancel(true);
			_ghostFuture = null;
		}
		this.set_ghostTime(-1);

		this.setGhost(false);
		this.setGhostCanTalk(true);
		this.setReserveGhost(false);

		//		if (_hellFuture != null) {
		//			_hellFuture.cancel(true);
		//			_hellFuture = null;
		//		}
		/*
		 * if (_autoUpdateFuture != null) { _autoUpdateFuture.cancel(true);
		 * _autoUpdateFuture = null; }
		 */

	}
	public void death(final L1Character lastAttacker) {
		synchronized (this) {
			if (this.isDead()) {
				return;
			}
			this.inQuestGame = false;// opqlo 死亡副本結束
			this.setDead(true);
			this.setStatus(ActionCodes.ACTION_Die);
		}
		GeneralThreadPool.getInstance().execute(new PcDeath(this, lastAttacker));
	}
	private long _old_exp;

	public long getExpo() {
		return _old_exp;
	}

	public void onChangeExp() {
		if (this._old_exp != this.getExp()) {
			this._old_exp = this.getExp();

			final int level = ExpTable.getLevelByExp(this._old_exp);
			final int char_level = this.getLevel();
			final int gap = level - char_level;

			if (gap == 0) {
				if (level <= 127) {
					this.sendPackets(new S_Exp(this));
				} else {
					this.sendPackets(new S_OwnCharStatus(this));
				}
				return;
			}

			if (gap > 0) {
				this.levelUp(gap);

			} else if (gap < 0) {
				this.levelDown(gap);
			}
		}
	}

	@Override
	/**對其他傳送封包*/
	public void onPerceive(L1PcInstance perceivedFrom) {
		if (isGmInvis() || isGhost()) {
			return;
		}
		if (isInvisble() && !perceivedFrom.hasSkillEffect(GMSTATUS_FINDINVIS)) {
			return;
		}
		if (perceivedFrom.hasSkillEffect(GMSTATUS_HPBAR)) { 
			perceivedFrom.sendPackets(new S_HPMeter(this)); 
		}
		perceivedFrom.addKnownObject(this);
		perceivedFrom.sendPackets(new S_OtherCharPacks(this, perceivedFrom.hasSkillEffect(GMSTATUS_FINDINVIS))); // 自分の情報を送る
		if (isInParty() && getParty().isMember(perceivedFrom)) { // PTメンバーならHPメーターも送る
			perceivedFrom.sendPackets(new S_HPMeter(this));
		}

		if (isPrivateShop()) {
			perceivedFrom.sendPackets(new S_DoActionShop(getId(),ActionCodes.ACTION_Shop, getShopChat()));
		}
		// opqlo 修正紫名更新問題
		final int time = getSkillEffectTimeSec(PC_IsPinkName);
		if (isPinkName() && time >0) {
			perceivedFrom.sendPackets(new S_PinkName(getId(), time));
		}
		//		else if(this.getMapId() == 70){//決鬥場
		//			perceivedFrom.sendPackets(new S_PinkName(getId(), 10*60*1000));
		//			//			perceivedFrom.sendPackets(new S_PacketBox(S_PacketBox.MSG_DUEL,this.getId(), perceivedFrom.getId()));
		//		}
		// opqlo 修正紫名更新問題
		if (isCrown()) { // 君主
			final L1Clan clan = WorldClan.get().getClan(getClanname());
			if (clan != null) {
				if (getId() == clan.getLeaderId() // 血盟主で城主クラン
						&& clan.getCastleId() != 0) {
					perceivedFrom.sendPackets(new S_CastleMaster(clan.getCastleId(), getId()));
				}
			}
		}
	}

	/**
	 * 清除離開可視範圍物件
	 */
	private void removeOutOfRangeObjects() {
		for (final L1Object known : getKnownObjects()) {
			if (known == null) {
				continue;
			}

			if (Config.PC_RECOGNIZE_RANGE == -1) {
				if (!getLocation().isInScreen(known.getLocation())) { // 画面外
					removeKnownObject(known);
					sendPackets(new S_RemoveObject(known));
					/*
					 * if(known instanceof L1MonsterInstance){
					 * ((L1MonsterInstance) known).RemoveHpList(this); }
					 */
				}
			} else {
				if (getLocation().getTileLineDistance(known.getLocation()) > Config.PC_RECOGNIZE_RANGE) {
					removeKnownObject(known);
					sendPackets(new S_RemoveObject(known));
					/*
					 * if(known instanceof L1MonsterInstance){
					 * ((L1MonsterInstance) known).RemoveHpList(this); }
					 */
				}
			}
		}
	}

	/**
	 * 可見物更新處理
	 */
	public void updateObject() {
		if (getOnlineStatus() != 1) {
			return;
		}
		if(this.isTeleport()){
			return;
		}
		removeOutOfRangeObjects();
		//		L1MerchantInstance merchant;
		//		L1DwarfInstance dwarf;
		// 指定可視範圍資料更新
		for (final L1Object visible : L1World.getInstance().getVisibleObjects(this, Config.PC_RECOGNIZE_RANGE)) {

			// 指定可視範圍資料更新
			//			if (visible instanceof L1MerchantInstance) {// 對話NPC
			//				if (!knownsObject(visible)) {
			//					merchant = (L1MerchantInstance) visible;
			//					// 未認知物件 執行物件封包發送
			//					merchant.onPerceive(this);
			//				}
			//				continue;
			//			}
			//			if (visible instanceof L1DwarfInstance) {// 倉庫NPC
			//				if (!knownsObject(visible)) {
			//					dwarf = (L1DwarfInstance) visible;
			//					// 未認知物件 執行物件封包發送
			//					dwarf.onPerceive(this);
			//				}
			//				continue;
			//			}
			//
			//			if (visible instanceof L1FieldObjectInstance) {// 景觀
			//				if (!knownsObject(visible)) {
			//					final L1FieldObjectInstance npc = (L1FieldObjectInstance) visible;
			//					// 未認知物件 執行物件封包發送
			//					npc.onPerceive(this);
			//				}
			//				continue;
			//			}

			if (!knownsObject(visible)) {
				visible.onPerceive(this);

			} else if (visible instanceof L1NpcInstance) {
				final L1NpcInstance npc = (L1NpcInstance) visible;

				if (getLocation().isInScreen(npc.getLocation())
							&& npc.getHiddenStatus() != 0) {
					npc.approachPlayer(this);
				}

				/**OPQLO 血條封包傳送調整*/
				if (visible instanceof L1MonsterInstance){
					((L1MonsterInstance) visible).HpBar();

				} else if (hasSkillEffect(GMSTATUS_HPBAR)
						&& (visible instanceof L1SummonInstance 
								|| visible instanceof L1PetInstance)) {
						sendPackets(new S_HPMeter((L1Character) visible)); 
					}

			}else if(visible instanceof L1PcInstance && hasSkillEffect(GMSTATUS_HPBAR)){
				sendPackets(new S_HPMeter((L1Character) visible)); 
			}

			// TODO 所有人都看的到怪物血條

			//			if (visible instanceof L1MonsterInstance
			//					||visible instanceof L1PcInstance
			//					||visible instanceof L1SummonInstance
			//					||visible instanceof L1PetInstance) {
			//				if (visible instanceof L1MonsterInstance) {
			//					sendPackets(new S_HPMeter((L1Character) visible)); 
			//					//					System.out.println(visible.getId() + " / " +((L1Character)visible).getName()); 
			//				} else if (hasSkillEffect(GMSTATUS_HPBAR)) { 
			//					sendPackets(new S_HPMeter((L1Character) visible)); 
			//				} 
			//			}

			// TODO 所有人都看的到怪物血條
			//			if (hasSkillEffect(GMSTATUS_HPBAR)) {
			//				if (L1HpBar.isHpBarTarget(visible)) {
			//					sendPackets(new S_HPMeter((L1Character) visible));
			//				}
			//			}
			/*
			 * }else if(visible instanceof L1MonsterInstance){
			 * if(((L1MonsterInstance) visible).InHpList(this)){ sendPackets(new
			 * S_HPMeter((L1Character) visible));
			 * 
			 * } }
			 */
		}
	}

	private void sendVisualEffect() {
		int poisonId = 0;
		if (getPoison() != null) { // 毒状態
			poisonId = getPoison().getEffectId();
		}
		if (getParalysis() != null) { // 麻痺状態
			// 麻痺エフェクトを優先して送りたい為、poisonIdを上書き。
			poisonId = getParalysis().getEffectId();
		}
		if (poisonId != 0) { // このifはいらないかもしれない
			sendPacketsAll(new S_Poison(getId(), poisonId));
		}
	}

	public void sendVisualEffectAtLogin() {

		if (getClanid() != 0) { // クラン所属
			final L1Clan clan = WorldClan.get().getClan(getClanname());
			if (clan != null) {
				if (isCrown() && getId() == clan.getLeaderId() && // プリンスまたはプリンセス、かつ、血盟主で自クランが城主
						clan.getCastleId() != 0) {
					sendPackets(new S_CastleMaster(clan.getCastleId(), getId()));
				}
			}
		}

		sendVisualEffect();
	}

	public void sendVisualEffectAtTeleport() {
		//		if (isDrink()) { // liquorで酔っている
		//			sendPackets(new S_Liquor(getId(), 1));
		//		}
		//		else if (isSpeedUp()) {
		//			sendPacketsAll(new S_Liquor(getId(), 8)); // 人物 * 1.15
		//		}
		sendVisualEffect();
	}

	private ArrayList<Integer> _skillList = new ArrayList<Integer>();

	/**
	 * 加入技能編號列表
	 * 
	 * @param skillid
	 */
	public void setSkillMastery(final int skillid) {
		if (!this._skillList.contains(new Integer(skillid))) {
			this._skillList.add(new Integer(skillid));
		}
	}

	/**
	 * 移出技能編號列表
	 * 
	 * @param skillid
	 */
	public void removeSkillMastery(final int skillid) {
		if (this._skillList.contains(new Integer(skillid))) {
			this._skillList.remove(new Integer(skillid));
		}
	}

	/**
	 * 傳回是否具有該技能使用權
	 * 
	 * @param skillid
	 * @return
	 */
	public boolean isSkillMastery(final int skillid) {
		return this._skillList.contains(new Integer(skillid));
	}

	/**
	 * 清空
	 */
	public void clearSkillMastery() {
		this._skillList.clear();
	}

	public L1PcInstance() {
		_accessLevel = 0;
		_currentWeapon = 0;
		_equipSlot = new L1EquipmentSlot(this); // コンストラクタでthisポインタを渡すのは安全だろうか・・・
		_inventory = new L1PcInventory(this);
		_dwarf = new L1DwarfInventory(this);
		_dwarfForElf = new L1DwarfForElfInventory(this);
		_bookmarks = new ArrayList<L1BookMark>();
		_quest = new L1Quest(this);
		_dollList = new L1DollList(this);
	}

	@Override
	public void setCurrentHp(final int i) {
		if (getCurrentHp() == i) {
			return;
		}
		final int currentHp = Math.min(i, getMaxHp());
		setCurrentHpDirect(currentHp);
		if(this.getConfig().isHpBarRateX10()){
			sendPackets(new S_HPUpdate(currentHp, getMaxHp()));
		}else{
		sendPackets(new S_HPUpdate((currentHp/10), (getMaxHp()/10)));
		}
		if (isInParty()) { // パーティー中
			getParty().updateMiniHP(this);
		}
	}

	@Override
	public void setCurrentMp(final int i) {
		if (getCurrentMp() == i) {
			return;
		}
		final int maxmp = getMaxMp();
		if (isGm()) {
			setCurrentMpDirect(maxmp);
			sendPackets(new S_MPUpdate(maxmp, maxmp));
			return;
		}
		final int currentMp = Math.min(i, maxmp);

		setCurrentMpDirect(currentMp);
		sendPackets(new S_MPUpdate(currentMp, maxmp));
	}

	@Override
	public L1PcInventory getInventory() {
		return _inventory;
	}

	public L1DwarfInventory getDwarfInventory() {
		return _dwarf;
	}

	public L1DwarfForElfInventory getDwarfForElfInventory() {
		return _dwarfForElf;
	}

	public boolean isGmInvis() {
		return _gmInvis;
	}

	public void setGmInvis(final boolean flag) {
		_gmInvis = flag;
	}

	public int getCurrentWeapon() {
		return _currentWeapon;
	}

	public void setCurrentWeapon(final int i) {
		_currentWeapon = i;
	}

	/** 職業類型 0=王子 1=騎士 2=妖精 3=法師 4=黑暗妖精 5=龍騎士 6=幻術士 */
	public int getType() {
		return _type;
	}

	/** 職業類型 0=王子 1=騎士 2=妖精 3=法師 4=黑暗妖精 5=龍騎士 6=幻術士 */
	public void setType(final int i) {
		_type = i;
	}

	public short getAccessLevel() {
		return _accessLevel;
	}

	public void setAccessLevel(final short i) {
		_accessLevel = i;
	}

	public int getClassId() {
		return _classId;
	}

	public void setClassId(final int i) {
		_classId = i;
		_classFeature = L1ClassFeature.newClassFeature(i);
	}

	/**變形藥水用變更外觀編號opqlo**/
	public void changeSex(final int i){
		_classId = i;
	}

	private L1ClassFeature _classFeature = null;

	public L1ClassFeature getClassFeature() {
		return _classFeature;
	}

	@Override
	public synchronized long getExp() {
		return _exp;
	}

	@Override
	public synchronized void setExp(final long i) {
		_exp = i;
	}

	public synchronized void addExp(long exp) {
		/*	_exp += exp;
		if (_exp > ExpTable.MAX_EXP) {
			_exp = ExpTable.MAX_EXP;
		}*/
		final long allexp = Math.min(0x6ECF16D0, (_exp + exp));
		_exp = allexp;
	}

	private void levelUp(final int gap) {
		try {
			this.resetLevel();

			// 復活のポーション
			if (getLevel() == 99 && Config.ALT_REVIVAL_POTION) {
				if (this.getInventory().findItemId(43000) == null) {
					L1Item l1item = ItemTable.getInstance().getTemplate(43000);
					if (l1item != null) {
						getInventory().storeItem(43000, 1);
						sendPackets(new S_ServerMessage(403, l1item.getName()));
					} else {
						sendPackets(new S_SystemMessage("返生藥水取得失敗。"));
					}
				}
			}
		} catch (Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
			sendPackets(new S_SystemMessage("返生藥水取得失敗。"));
		}

		for (int i = 0; i < gap; i++) {
			final short randomHp = CalcStat.calcStatHp(getType(),
					getBaseMaxHp(), getBaseCon(), getOriginalHpup());
			final short randomMp = CalcStat.calcStatMp(getType(),
					getBaseMaxMp(), getBaseWis(), getOriginalMpup());
			addBaseMaxHp(randomHp);
			addBaseMaxMp(randomMp);
			// TODO 升級後血魔補滿
			if (Config.MaxHPMP) {
				setCurrentHp(getMaxHp());
				setCurrentMp(getMaxMp());
			}
			// TODO 升級後血魔補滿
		}
		resetBaseHitup();
		resetBaseDmgup();
		resetBaseAc();
		resetBaseMr();
		final int nowLevel = getLevel();
		if (nowLevel > getHighLevel()) {
			setHighLevel(nowLevel);
		}
		if (nowLevel >= 51) {
			// ボーナスステータス
			if (nowLevel - 50 > getBonusStats()) {
				if (全屬性總和 < ((Config.BONUS_STATS1 * 6))) {// TODO 調整能力值上限
					sendPackets(new S_bonusstats(getId(), 1));
				}
			}
		}
		// TODO　 超過 13等傳出新手村by hot183
		if (nowLevel >= 14) {
			final short outmap = getMapId();
			switch (outmap) {
			case 2005:
				L1Teleport.teleport(this, 33080, 33392, (short) 4, (byte) 5,
						true); // TODO <-銀騎士村座標
				break;
			case 777:
				if (nowLevel >= 52) {// 見捨てられた者たちの地(影の神殿)
					L1Teleport.teleport(this, 34043, 32184, (short) 4, 5, true); // 象牙の塔前
				}
				break;
			case 778:
			case 779:
				if (nowLevel >= 52) { // 指定レベル
					L1Teleport.teleport(this, 32608, 33178, (short) 4, 5, true); // WB
				}
				break;
			}
			// TODO　 超過 13等傳出新手村by hot183
		}

		try {
			save();
		} catch (Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		} finally {
			sendPackets(new S_OwnCharStatus(this));
			// TODO 升級獎勵道具 by 阿傑
			Reward.getInstance().getItem(this);
			// TODO　升級獎勵道具 by 阿傑
			// TODO 處理新手保護系統(遭遇的守護)狀態資料的變動
			checkNoviceType();
		}
	}

	private void levelDown(final int gap) {

		resetLevel();

		for (int i = 0; i > gap; i--) {
			// レベルダウン時はランダム値をそのままマイナスする為に、base値に0を設定
			final short randomHp = CalcStat.calcStatHp(getType(), 0,
					getBaseCon(), getOriginalHpup());
			final short randomMp = CalcStat.calcStatMp(getType(), 0,
					getBaseWis(), getOriginalMpup());
			addBaseMaxHp((short) -randomHp);
			addBaseMaxMp((short) -randomMp);
		}
		resetBaseHitup();
		resetBaseDmgup();
		resetBaseAc();
		resetBaseMr();
		if (Config.LEVEL_DOWN_RANGE != 0) {
			if (getHighLevel() - getLevel() >= Config.LEVEL_DOWN_RANGE) {
				sendPackets(new S_ServerMessage(64)); // ワールドとの接続が切断されました。
				this.getNetConnection().close();
				_log.info(String.format("角色等級超出容許範圍(%s)已被強制切斷連線。", getName()));
			}
		}
		// 更新人物資訊
		sendPackets(new S_OwnCharStatus(this));
		// TODO 處理新手保護系統(遭遇的守護)狀態資料的變動
		checkNoviceType();
		try {
			// DBにキャラクター情報を書き込む
			save();
		} catch (Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
	}

	private int _PKcount; // ● PKカウント

	public int get_PKcount() {
		return _PKcount;
	}

	public void set_PKcount(final int i) {
		_PKcount = Math.max(0 ,i);
		_PKcount = Math.min(i, 300);
	}

	public void add_PKcount(){
		_PKcount++;
		_PKcount = Math.min(_PKcount, 300);
		if(_PKcount >=300){
			this.beginHell();
		}
	}
	public void remove_PKcount(){
		_PKcount--;
		_PKcount = Math.max(0 , _PKcount);
	}

	private int _PkCountForElf; // ● PKカウント(エルフ用)

	public int getPkCountForElf() {
		return _PkCountForElf;
	}

	public void setPkCountForElf(final int i) {
		_PkCountForElf = i;
	}

	private int _clanid; // ● クランＩＤ

	public int getClanid() {
		return _clanid;
	}

	public void setClanid(final int i) {
		_clanid = i;
	}

	private String clanname; // ● クラン名

	public String getClanname() {
		return clanname;
	}

	public void setClanname(final String s) {
		clanname = s;
	}

	// 参照を持つようにしたほうがいいかもしれない
	public L1Clan getClan() {
		return WorldClan.get().getClan(getClanname());
	}

	private int _clanRank; // ● クラン内のランク(血盟君主、ガーディアン、一般、見習い)

	public int getClanRank() {
		return _clanRank;
	}

	public void setClanRank(final int i) {
		_clanRank = i;
	}

	// TODO 角色誕生by99團隊
	private Timestamp _birthday;

	public Timestamp getBirthday() {
		return _birthday;
	}

	public int getSimpleBirthday() {
		if (_birthday != null) {
			final SimpleDateFormat SimpleDate = new SimpleDateFormat("yyyyMMdd");
			int BornTime = Integer.parseInt(SimpleDate.format(_birthday
					.getTime()));
			return BornTime;
		} else {
			return 0;
		}
	}

	public void setBirthday(final Timestamp time) {
		_birthday = time;
	}

	public void setBirthday() {
		_birthday = new Timestamp(System.currentTimeMillis());
	}

	// TODO 角色誕生by99團隊

	private byte _sex; // ● 性別

	public byte get_sex() {
		return _sex;
	}

	public void set_sex(final int i) {
		_sex = (byte) i;
	}

	public boolean isGm() {
		return _gm;
	}

	public void setGm(final boolean flag) {
		_gm = flag;
	}

	public boolean isMonitor() {
		return _monitor;
	}

	public void setMonitor(final boolean flag) {
		_monitor = flag;
	}

	private L1PcInstance getStat() {
		return null;
	}

	public void reduceCurrentHp(double d, final L1Character l1character) {
		getStat().reduceCurrentHp(d, l1character);
	}

	/**
	 * 指定されたプレイヤー群にログアウトしたことを通知する
	 * 
	 * @param playersList
	 *            通知するプレイヤーの配列
	 */
	private void notifyPlayersLogout(final List<L1PcInstance> playersArray) {
		for (final L1PcInstance player : playersArray) {
			if (player.knownsObject(this)) {
				player.removeKnownObject(this);
				player.sendPackets(new S_RemoveObject(this));
			}
		}
	}

	public void logout() {
		GameServer.getInstance().removeOnlinePc(_netConnection);
		// 保留技能紀錄
		CharBuffTable.DeleteBuff(this);
		CharBuffTable.SaveBuff(this);
		this.clearSkillEffectTimer();

		// 解除舊座標障礙宣告
		this.getMap().setPassable(this.getLocation(), true);

		final L1World world = L1World.getInstance();

		/** 解除血盟倉庫目前使用者 */
		if (getClanid() != 0) {
			final L1Clan clan = WorldClan.get().getClan(getClanname());
			if (clan != null) {
				if (clan.getWarehouseUsingChar() == getId()) { // 自キャラがクラン倉庫使用中
					clan.setWarehouseUsingChar(0); // 解除血盟倉庫目前使用者
				}
			}
		}
		this.notifyPlayersLogout(getKnownPlayers());
		world.removeVisibleObject(this);
		world.removeObject(this);
		this.notifyPlayersLogout(world.getRecognizePlayer(this));
		// this._inventory.clearItems();
		this._dwarf.clearItems();
		this._dwarfForElf.clearItems();
		this.removeAllKnownObjects();
		this.stopHpRegeneration();
		this.stopMpRegeneration();
		this.setDead(true); // 使い方おかしいかもしれないけど、ＮＰＣに消滅したことをわからせるため
		this.setNetConnection(null);
		this.setPacketOutput(null);
		// 清空清單資料
		ListMapUtil.clear(this._Chatlist);
		ListMapUtil.clear(this._sellList);
		ListMapUtil.clear(this._buyList);
		ListMapUtil.clear(this._skillList);
		if(this._excludingList !=null){
			this._excludingList.clear();
		}
	}

	public ClientThread getNetConnection() {
		return _netConnection;
	}

	public void setNetConnection(final ClientThread clientthread) {
		_netConnection = clientthread;
	}

	public boolean isInParty() {
		return getParty() != null;
	}

	public L1Party getParty() {
		return _party;
	}

	public void setParty(final L1Party p) {
		_party = p;
	}

	public boolean isInChatParty() {
		return getChatParty() != null;
	}

	public L1ChatParty getChatParty() {
		return _chatParty;
	}

	public void setChatParty(final L1ChatParty cp) {
		_chatParty = cp;
	}

	public int getPartyID() {
		return _partyID;
	}

	public void setPartyID(final int partyID) {
		_partyID = partyID;
	}

	// opqlo 斷線重登會自動加入原本隊伍
//	private int _LogPartyId;
//
//	public void setLogPartyId(final int id) {
//		_LogPartyId = id;
//	}
//
//	public int getLogPartyId() {
//		return _LogPartyId;
//	}
//
//	public void ReSetPartyID() {
//		if (_LogPartyId < 1) {
//			return;
//		}
//		if (TeamLog.getInstance().getPartyList(_LogPartyId) != null) {
//			TeamLog.getInstance().getPartyList(_LogPartyId).addMember(this);
//			if (this.getParty() != null) {
//				for (final L1PcInstance pc : this.getParty().getMembers()) {
//					pc.sendPackets(new A_ColorMessage(11, "[隊伍訊息]: 隊員[ "+ this.getName() + " ]上線了。"));
//				}
//			}
//		} else {
//			_LogPartyId = 0;
//		}
//
//	}

	// opqlo 斷線重登會自動加入原本隊伍

	public int getTradeID() {
		return _tradeID;
	}

	public void setTradeID(final int tradeID) {
		_tradeID = tradeID;
	}

	public void setTradeOk(final boolean tradeOk) {
		_tradeOk = tradeOk;
	}

	public boolean getTradeOk() {
		return _tradeOk;
	}

	public int getTempID() {
		return _tempID;
	}

	public void setTempID(final int tempID) {
		_tempID = tempID;
	}

	public boolean isTeleport() {
		return _isTeleport;
	}

	public void setTeleport(final boolean flag) {
		_isTeleport = flag;
		if(!flag){
			this.sendPackets(new S_Paralysis(S_Paralysis.TYPE_TELEPORT_UNLOCK, true));
		}
	}

	public boolean isDrink() {
		return _isDrink;
	}

	public void setDrink(final boolean flag) {
		_isDrink = flag;
	}

	public boolean isGres() {
		return _isGres;
	}

	public void setGres(final boolean flag) {
		_isGres = flag;
	}

	public boolean isPinkName() {
		return _isPinkName;
	}

	public void setPinkName(final boolean flag) {
		_isPinkName = flag;
		// opqlo 修正紫名更新問題
		if (!flag && hasSkillEffect(PC_IsPinkName)) {
			killSkillEffectTimer(PC_IsPinkName);
		}
		// opqlo 修正紫名更新問題
	}

	private List<L1PrivateShopSellList>_sellList = Lists.newList();

	public List<L1PrivateShopSellList> getSellList() {
		return _sellList;
	}

	private List<L1PrivateShopBuyList> _buyList = Lists.newList();

	public List<L1PrivateShopBuyList> getBuyList() {
		return _buyList;
	}

	private byte[] _shopChat;

	public void setShopChat(final byte[] chat) {
		_shopChat = chat;
	}

	public byte[] getShopChat() {
		return _shopChat;
	}

	private boolean _isPrivateShop = false;

	public boolean isPrivateShop() {
		return _isPrivateShop;
	}

	public void setPrivateShop(final boolean flag) {
		_isPrivateShop = flag;
	}

	private boolean _isTradingInPrivateShop = false;

	public boolean isTradingInPrivateShop() {
		return _isTradingInPrivateShop;
	}

	public void setTradingInPrivateShop(final boolean flag) {
		_isTradingInPrivateShop = flag;
	}

	private int _partnersPrivateShopItemCount = 0; // 閲覧中の個人商店のアイテム数

	public int getPartnersPrivateShopItemCount() {
		return _partnersPrivateShopItemCount;
	}

	public void setPartnersPrivateShopItemCount(final int i) {
		_partnersPrivateShopItemCount = i;
	}

	// private PacketOutput _out;

	// public void setPacketOutput(final PacketOutput out) {
	// _out = out;
	// }

	private EncryptExecutor _out;// 封包加密管理

	/**
	 * 設置封包加密管理
	 * 
	 * @param out
	 */
	public void setPacketOutput(final EncryptExecutor out) {
		this._out = out;
	}

	/**
	 * 關閉連線線程
	 */
	private void close() {
		try {
			this.getNetConnection().close();
			_log.info(getName() + " 發送封包失敗，強制中斷。");
		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
	}

	/**
	 * 發送單體封包
	 * 
	 * @param packet
	 *            封包
	 */
	public void sendPackets(final ServerBasePacket serverbasepacket) {
		if (this._out == null) {
			return;
		}
		try {
			_out.encrypt(serverbasepacket);

		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
			this.close();
			this._out = null;
		}
	}

	@Override
	public void onAction(final L1PcInstance attacker) {
		// XXX:NullPointerException回避。onActionの引数の型はL1Characterのほうが良い？
		if (attacker == null) {
			return;
		}
		// テレポート処理中
		if (isTeleport()) {
			return;
		}
		// 攻撃される側または攻撃する側がセーフティーゾーン
		if (getZoneType() == 1 || attacker.getZoneType() == 1) {
			// 攻撃モーション送信
			final L1AttackModel attack_mortion = new L1AttackPc(attacker, this);
			attack_mortion.action();
			return;
		}

		if (checkNonPvP(this, attacker) == true) {
			// 攻撃モーション送信
			final L1AttackModel attack_mortion = new L1AttackPc(attacker, this);
			attack_mortion.action();
			return;
		}

		if (getCurrentHp() > 0 && !isDead()) {
			attacker.delInvis();

			boolean isCounterBarrier = false;
			final L1AttackModel attack = new L1AttackPc(attacker, this);
			if (attack.calcHit()) {
				if (hasSkillEffect(COUNTER_BARRIER)) {
					final L1Magic magic = new L1Magic(this, attacker);
					final boolean isProbability = magic.calcProbabilityMagic(COUNTER_BARRIER);
					final boolean isShortDistance = attack.isShortDistance();
					if (isProbability && isShortDistance) {
						isCounterBarrier = true;
					}
				}
				if (!isCounterBarrier) {
					attacker.setPetTarget(this);
					attack.calcDamage();
					attack.calcStaffOfMana();
					attack.addChaserAttack();

				}
			}
			if (isCounterBarrier) {
				attack.actionCounterBarrier();
				attack.commitCounterBarrier();
			} else {
				attack.action();
				attack.commit();
			}
		}
	}

	public boolean checkNonPvP(final L1PcInstance pc, final L1Character target) {
		L1PcInstance targetpc = null;
		if (target instanceof L1PcInstance) {
			targetpc = (L1PcInstance) target;
		} else if (target instanceof L1PetInstance) {
			targetpc = (L1PcInstance) ((L1PetInstance) target).getMaster();
		} else if (target instanceof L1SummonInstance) {
			targetpc = (L1PcInstance) ((L1SummonInstance) target).getMaster();
		}
		if (targetpc == null) {
			return false; // 相手がPC、サモン、ペット以外
		}
		if (!Config.ALT_NONPVP) { // Non-PvP設定
			if (getMap().isCombatZone(getLocation())) {
				return false;
			}

			// 取回全部戰爭清單
			for (final L1War war : WorldWar.get().getWarList()) {
				if ((pc.getClanid() != 0) && (targetpc.getClanid() != 0)) { // 共にクラン所属中
					final boolean same_war = war.checkClanInSameWar(
							pc.getClanname(), targetpc.getClanname());
					if (same_war == true) { // 同じ戦争に参加中
						return false;
					}
				}
			}
			// Non-PvP設定でも戦争中は布告なしで攻撃可能
			if (target instanceof L1PcInstance) {
				final L1PcInstance targetPc = (L1PcInstance) target;
				if (isInWarAreaAndWarTime(pc, targetPc)) {
					return false;
				}
			}
			return true;
		} else {
			return false;
		}
	}

	public boolean isInWarAreaAndWarTime(final L1PcInstance pc,
			final L1PcInstance target) {
		// pcとtargetが戦争中に戦争エリアに居るか
		final int castleId = L1CastleLocation.getCastleIdByArea(pc);
		final int targetCastleId = L1CastleLocation.getCastleIdByArea(target);
		if (castleId != 0 && targetCastleId != 0 && castleId == targetCastleId) {
			if (ServerWarExecutor.get().isNowWar(castleId)) {
				return true;
			}
		}
		return false;
	}

	public void setPetTarget(final L1Character target) {
		final Object[] petList = getPetList().values().toArray();
		for (final Object pet : petList) {
			if (pet instanceof L1PetInstance) {
				final L1PetInstance pets = (L1PetInstance) pet;
				pets.setMasterTarget(target);
			} else if (pet instanceof L1SummonInstance) {
				final L1SummonInstance summon = (L1SummonInstance) pet;
				summon.setMasterTarget(target);
			}
		}
	}

	public void delInvis() {
		// 魔法接続時間内はこちらを利用
		if (hasSkillEffect(INVISIBILITY)) { // インビジビリティ
			killSkillEffectTimer(INVISIBILITY);
			sendPackets(new S_Invis(getId(), 0));
			broadcastPacketAll(new S_OtherCharPacks(this));

		} else if (hasSkillEffect(BLIND_HIDING)) { // ブラインド ハイディング
			killSkillEffectTimer(BLIND_HIDING);
			sendPackets(new S_Invis(getId(), 0));
			broadcastPacketAll(new S_OtherCharPacks(this));
		}
	}

	public void delBlindHiding() {
		// 魔法接続時間終了はこちら
		killSkillEffectTimer(BLIND_HIDING);
		sendPackets(new S_Invis(getId(), 0));
		broadcastPacketAll(new S_OtherCharPacks(this));
	}

	// 魔法のダメージの場合はここを使用 (ここで魔法ダメージ軽減処理) attr:0.無属性魔法,1.地魔法,2.火魔法,3.水魔法,4.風魔法
	public void receiveDamage(final L1Character attacker, int damage,
			final int attr) {
		final int player_mr = getMr();
		final int rnd = Random.nextInt(100) + 1;
		if (player_mr >= rnd) {
			damage /= 2;
		}
		receiveDamage(attacker, damage, false);
	}

	public void receiveManaDamage(final L1Character attacker, final int mpDamage) { // 攻撃でＭＰを減らすときはここを使用
		if (mpDamage > 0 && !isDead()) {
			delInvis();
			if (attacker instanceof L1PcInstance) {
				L1PinkName.onAction(this, attacker);
				//				if( ((L1PcInstance) attacker).isPinkName()) {
				//					// ガードが画面内にいれば、攻撃者をガードのターゲットに設定する
				//					for (final L1Object object : L1World.getInstance().getVisibleObjects(attacker)) {
				//						if (object instanceof L1GuardInstance) {
				//							final L1GuardInstance guard = (L1GuardInstance) object;
				//							guard.setTarget(((L1PcInstance) attacker));
				//						}
				//					}
				//				}
			}

			final int newMp = Math.min(getMaxMp(), getCurrentMp() - mpDamage);

			setCurrentMp(Math.max(0, newMp));
		}
	}

	public double _oldTime = 0; // 連続魔法ダメージの軽減に使用する

	public void receiveDamage(final L1Character attacker, double damage,
			final boolean isMagicDamage) { // 攻撃でＨＰを減らすときはここを使用
		if (getCurrentHp() > 0 && !isDead()) {
			if (attacker != this) {
				if (!(attacker instanceof L1EffectInstance)
						&& !knownsObject(attacker)
						&& attacker.getMapId() == this.getMapId()) {
					attacker.onPerceive(this);
				}
			}
			if (isMagicDamage == true) { // 連続魔法ダメージによる軽減
				final double nowTime = (double) System.currentTimeMillis();
				final double interval = (20D - (nowTime - _oldTime) / 100D) % 20D;

				if (damage > 0) {
					if (interval > 0) {
						damage *= (1D - interval / 30D);
					} else if (damage <= 1) {
						damage = 0;
					}
					if (damage < 1) {
						damage = 0;
					}
					_oldTime = nowTime; // 次回のために時間を保存

				}
			}
			if (damage > 0) {
				delInvis();
				if (attacker instanceof L1PcInstance) {
					L1PinkName.onAction(this, attacker);
					//					if(((L1PcInstance) attacker).isPinkName()) {
					//						for (final L1Object object : L1World.getInstance().getVisibleObjects(attacker)) {
					//							if (object instanceof L1GuardInstance) {
					//								final L1GuardInstance guard = (L1GuardInstance) object;
					//								guard.setTarget(((L1PcInstance) attacker));
					//							}
					//						}
					//					}
				}
				removeSkillEffect(FOG_OF_SLEEPING);

			}
			final boolean NotMe = getId() != attacker.getId();
			if (hasSkillEffect(MORTAL_BODY) && NotMe) {
				final int rnd = Random.nextInt(100) + 1;
				if (damage > 0 && rnd <= 20) {// TODO リニューアル前は10%
					if (attacker instanceof L1PcInstance) {
						final L1PcInstance attackPc = (L1PcInstance) attacker;
						attackPc.sendPacketsX10(new S_DoActionGFX(attackPc
								.getId(), ActionCodes.ACTION_Damage));
						attackPc.receiveDamage(this, 30, false);
					} else if (attacker instanceof L1NpcInstance) {
						final L1NpcInstance attackNpc = (L1NpcInstance) attacker;
						attackNpc.broadcastPacketAll(new S_DoActionGFX(attackNpc
								.getId(), ActionCodes.ACTION_Damage));
						attackNpc.receiveDamage(this, 30);
					}
				}
			} else if (attacker.hasSkillEffect(JOY_OF_PAIN) && NotMe) {// 疼痛的歡愉
				final int nowDamage = (getMaxHp() - getCurrentHp()) / 5;
				if (nowDamage > 0) {
					final S_DoActionGFX Gfx = new S_DoActionGFX(attacker.getId(), ActionCodes.ACTION_Damage);
					if (attacker instanceof L1PcInstance) {
						final L1PcInstance attackPc = (L1PcInstance) attacker;
						if (attackPc.hasSkillEffect(JOY_OF_PAIN)) {
							attackPc.killSkillEffectTimer(JOY_OF_PAIN);
						}
						attackPc.sendPacketsX10(Gfx);
						attackPc.receiveDamage(this, (nowDamage), false);
					} else if (attacker instanceof L1NpcInstance) {
						final L1NpcInstance attackNpc = (L1NpcInstance) attacker;
						attackNpc.broadcastPacketAll(Gfx);
						final int rate = attackNpc.getDmgReduceRate();
						if (rate != 0) {
							attackNpc.receiveDamage(this,
									Math.max(1, nowDamage / rate));
						} else {
							attackNpc.receiveDamage(this, nowDamage);
						}
					}
				}
			}
			if (hasSkillEffect(ILLUSION_AVATAR)) {// TODO 幻術師技能幻覺幻身
				damage *= 1.2; // 被ダメ1.2倍
			}

			if(attacker instanceof L1MonsterInstance){
				final double rate = this.getAttrDef(((L1MonsterInstance)attacker).getNpcTemplate().get_weakAttr());
				if(rate!=0){
					damage -=damage * Math.max(0.5 , rate);//opqlo 屬性減傷 
				}
			}
			if(this.getInventory().checkEquipped(810052) && !this.hasSkillEffect(L1SkillId.IMMUNE_TO_HARM)
					&& Random.nextInt(100)+1 >97){//北含王冠
				new L1SkillUse().handleCommands(this, 68, this.getId(), this.getX(), this.getY(), null, 32, L1SkillUse.TYPE_GMBUFF);
			}
			final int newHp = Math.min(getMaxHp(), getCurrentHp()- (int) (damage));
			final boolean isDead = newHp < 1;
			if (isDead) {
				if (isGm()) {
					setCurrentHp(getMaxHp());
				} else {
					this.death(attacker);
				}
			} else {
				setCurrentHp(newHp);
			}
		} else if (!isDead()) { // 念のため
			_log.info("警告：玩家的ＨＰ減少處理有不正當的地方。※或者從最初開始ＨＰ０﹝L1PcInstance﹞。");
			this.death(attacker);
		}
	}

	// 死亡相關

	private int _delete_time = 0;// 死亡時間

	public void set_delete_time(final int time) {
		_delete_time = time;
	}

	public int get_delete_time() {
		return _delete_time;
	}



	/**
	 * <FONT COLOR="#0000ff">是否在參加攻城戰中</FONT>
	 * 
	 * @return true:是 false:不是
	 */
	public boolean castleWarResult() {
		if ((this.getClanid() != 0) && this.isCrown()) { // 具有血盟的王族
			final L1Clan clan = WorldClan.get().getClan(this.getClanname());
			if (clan.getCastleId() == 0) {
				// 取回全部戰爭清單
				for (final L1War war : WorldWar.get().getWarList()) {
					final int warType = war.getWarType();
					final boolean isInWar = war.checkClanInWar(this.getClanname());
					final boolean isAttackClan = war.checkAttackClan(this.getClanname());
					if ((this.getId() == clan.getLeaderId()) && (warType == 1) && isInWar && isAttackClan) {// 攻城戰中 攻擊方盟主死亡退出戰爭
						final String enemyClanName = war.getEnemyClanName(this.getClanname());
						if (enemyClanName != null) {
							war.ceaseWar(this.getClanname(), enemyClanName); // 結束
						}
					}
				}
			}
		}

		int castleId = 0;
		boolean isNowWar = false;
		castleId = L1CastleLocation.getCastleIdByArea(this);
		if (castleId != 0) { // 戰爭範圍旗幟內城堡ID
			isNowWar = ServerWarExecutor.get().isNowWar(castleId);
		}
		return isNowWar;
	}

	public boolean simWarResult(final L1Character lastAttacker) {
		if (getClanid() == 0) { // クラン所属していない
			return false;
		}
		if (Config.SIM_WAR_PENALTY) { // 模擬戦ペナルティありの場合はfalse
			return false;
		}
		L1PcInstance attacker = null;
		String enemyClanName = null;
		boolean sameWar = false;

		if (lastAttacker instanceof L1PcInstance) {
			attacker = (L1PcInstance) lastAttacker;
		} else if (lastAttacker instanceof L1PetInstance) {
			attacker = (L1PcInstance) ((L1PetInstance) lastAttacker)
					.getMaster();
		} else if (lastAttacker instanceof L1SummonInstance) {
			attacker = (L1PcInstance) ((L1SummonInstance) lastAttacker)
					.getMaster();
		} else {
			return false;
		}

		// 取回全部戰爭清單
		for (final L1War war : WorldWar.get().getWarList()) {
			final L1Clan clan = WorldClan.get().getClan(this.getClanname());

			final int warType = war.getWarType();
			final boolean isInWar = war.checkClanInWar(this.getClanname());
			if ((attacker != null) && (attacker.getClanid() != 0)) { // lastAttackerがPC、サモン、ペットでクラン所属中
				sameWar = war.checkClanInSameWar(this.getClanname(),
						attacker.getClanname());
			}

			if ((this.getId() == clan.getLeaderId()) && // 血盟主で模擬戦中
					(warType == 2) && (isInWar == true)) {
				enemyClanName = war.getEnemyClanName(this.getClanname());
				if (enemyClanName != null) {
					war.ceaseWar(this.getClanname(), enemyClanName); // 結束
				}
			}

			if ((warType == 2) && sameWar) {// 模擬戦で同じ戦争に参加中の場合、ペナルティなし
				return true;
			}
		}
		return false;
	}

	/**
	 * 經驗質恢復
	 */
	public void resExp() {

		final int oldlevel = this.getLevel();
		final long resexp = ExpTable.getResExpTable(oldlevel);
		;
		final long exp = resexp;
		if (exp <= 0) {
			return;
		}
		this.addExp(exp);
	}

	/**
	 * 經驗質懲罰
	 * 
	 * @return
	 */
	public long deathPenalty() {
		final int oldLevel = this.getLevel();
		final long penaltyexp = ExpTable.getdeathPenalty(oldLevel);
		final long exp = penaltyexp;
		final L1ItemInstance item = this.getInventory().findItemId(780069);//死幽谷卷軸
		if(item !=null){
			this.sendPackets(new S_SystemMessage(item.getName() +" 死亡後就消失了。"));
			this.getInventory().removeItem(item);
		}
		if (exp == 0) {
			return 0;
		}
		this.addExp(-exp);
		return exp;
	}

	private int _originalEr = 0; // ● オリジナルDEX ER補正

	public int getOriginalEr() {

		return _originalEr;
	}

	/** 取得角色ER值 */
	public int getEr() {
		if (hasSkillEffect(STRIKER_GALE)) {
			return 0;
		}
		int er = 0;
		switch (getType()) {
		case 1: // 騎士
			er = getLevel() / 4;
			break;
		case 0:
		case 2: // 王子、妖精
			er = getLevel() / 8;
			break;
		case 4:// 黑暗妖精
			er = getLevel() / 6;
			break;
		case 3:// 法師
			er = getLevel() / 10;
			break;
		case 5:// 龍騎士
			er = getLevel() / 7;
			break;
		case 6:// 幻術士
			er = getLevel() / 9;
			break;
		}
		final int dex = Math.min(getDex(), 25);
		er += (dex - 8) / 2;

		er += getOriginalEr();

		if (hasSkillEffect(DRESS_EVASION)) {
			er += 12;
		} else if (hasSkillEffect(SOLID_CARRIAGE)) {
			er += 15;
		}
		return er;
	}

	public L1BookMark getBookMark(final String name) {
		for (int i = 0; i < _bookmarks.size(); i++) {
			final L1BookMark element = _bookmarks.get(i);
			if (element.getName().equalsIgnoreCase(name)) {
				return element;
			}

		}
		return null;
	}

	public L1BookMark getBookMark(final int id) {
		for (int i = 0; i < _bookmarks.size(); i++) {
			final L1BookMark element = _bookmarks.get(i);
			if (element.getId() == id) {
				return element;
			}
		}
		return null;
	}

	public int getBookMarkSize() {
		return _bookmarks.size();
	}

	public void addBookMark(final L1BookMark book) {
		_bookmarks.add(book);
	}

	public void removeBookMark(final L1BookMark book) {
		_bookmarks.remove(book);
	}

	public L1ItemInstance getWeapon() {
		return _weapon;
	}

	public void setWeapon(final L1ItemInstance weapon) {
		_weapon = weapon;
	}

	public L1Quest getQuest() {
		return _quest;
	}

	/**
	 * 王族
	 * 
	 * @return
	 */
	public boolean isCrown() {
		return ((this.getClassId() == CLASSID_PRINCE) || (this.getClassId() == CLASSID_PRINCESS));
	}

	/**
	 * 騎士
	 * 
	 * @return
	 */
	public boolean isKnight() {
		return ((this.getClassId() == CLASSID_KNIGHT_MALE) || (this
				.getClassId() == CLASSID_KNIGHT_FEMALE));
	}

	/**
	 * 精靈
	 * 
	 * @return
	 */
	public boolean isElf() {
		return ((this.getClassId() == CLASSID_ELF_MALE) || (this.getClassId() == CLASSID_ELF_FEMALE));
	}

	/**
	 * 法師
	 * 
	 * @return
	 */
	public boolean isWizard() {
		return ((this.getClassId() == CLASSID_WIZARD_MALE) || (this
				.getClassId() == CLASSID_WIZARD_FEMALE));
	}

	/**
	 * 黑暗精靈
	 * 
	 * @return
	 */
	public boolean isDarkelf() {
		return ((this.getClassId() == CLASSID_DARK_ELF_MALE) || (this
				.getClassId() == CLASSID_DARK_ELF_FEMALE));
	}

	/**
	 * 龍騎士
	 * 
	 * @return
	 */
	public boolean isDragonKnight() {
		return ((this.getClassId() == CLASSID_DRAGON_KNIGHT_MALE) || (this
				.getClassId() == CLASSID_DRAGON_KNIGHT_FEMALE));
	}

	/**
	 * 幻術師
	 * 
	 * @return
	 */
	public boolean isIllusionist() {
		return ((this.getClassId() == CLASSID_ILLUSIONIST_MALE) || (this
				.getClassId() == CLASSID_ILLUSIONIST_FEMALE));
	}

	private static Logger _log = Logger.getLogger(L1PcInstance.class.getName());
	private ClientThread _netConnection;
	private int _classId;
	private int _type;
	private long _exp;
	private final L1Karma _karma = new L1Karma();
	private boolean _gm;
	private boolean _monitor;
	private boolean _gmInvis;
	private short _accessLevel;
	private int _currentWeapon;
	private final L1PcInventory _inventory;
	private final L1DwarfInventory _dwarf;
	private final L1DwarfForElfInventory _dwarfForElf;
	private L1ItemInstance _weapon;
	private L1Party _party;
	private L1ChatParty _chatParty;
	private int _partyID;
	private int _tradeID;
	private boolean _tradeOk;
	private int _tempID;
	private boolean _isTeleport = false;
	private boolean _isDrink = false;
	private boolean _isGres = false;
	private boolean _isPinkName = false;
	private final ArrayList<L1BookMark> _bookmarks;
	private L1Quest _quest;
	// private MpRegeneration _mpRegen;
	private MpRegenerationByDoll _mpRegenByDoll;
	private MpReductionByAwake _mpReductionByAwake;
	// private HpRegeneration _hpRegen;
	private HpRegenerationByDoll _hpRegenByDoll;// TODO 魔法娃娃回血功能 by hot183
	private boolean _mpRegenActive;
	private boolean _mpRegenActiveByDoll;
	private boolean _mpReductionActiveByAwake;
	private boolean _hpRegenActive;
	private boolean _hpRegenActiveByDoll;// TODO 魔法娃娃回血功能 by hot183
	private HashMap<Integer, ItemMakeByDoll> _itemMakeByDoll;// TODO 魔法娃娃DB化
	private L1EquipmentSlot _equipSlot;

	private String _accountName; // ● アカウントネーム

	public String getAccountName() {
		return _accountName;
	}

	public void setAccountName(String s) {
		_accountName = s;
	}

	private int _baseMaxHp = 0; // ● ＭＡＸＨＰベース（1～32767）

	public int getBaseMaxHp() {

		return (short) Math.max(_baseMaxHp, 1);
	}

	public void addBaseMaxHp(int i) {
		i += _baseMaxHp;
		i = IntRange.ensure(i, 1, 1000000000);

		addMaxHp(i - _baseMaxHp);
		_baseMaxHp = i;
	}

	private short _baseMaxMp = 0; // ● ＭＡＸＭＰベース（0～32767）

	public short getBaseMaxMp() {
		return _baseMaxMp;
	}

	public void addBaseMaxMp(short i) {
		i += _baseMaxMp;
		i = (short) IntRange.ensure(i, 1, 32767);

		addMaxMp(i - _baseMaxMp);
		_baseMaxMp = i;
	}

	// opqlo 七屬性破127
	private int _baseAc = 0; // ● ＡＣベース（-128～127）

	public int getBaseAc() {
		return _baseAc;
	}

	private int _originalAc = 0; // ● オリジナルDEX ＡＣ補正

	public int getOriginalAc() {

		return _originalAc;
	}

	public short 全屬性總和 = 0; // opqlo

	private short _baseStr = 0; // ● ＳＴＲベース（1～127）

	public short getBaseStr() {
		return _baseStr;
	}

	public void addBaseStr(short i) {
		全屬性總和 += i;
		i += _baseStr;
		i = (short) Math.max(i, 1);
		i = (short) Math.min(i, 32767);
		addStr((short) (i - _baseStr));
		_baseStr = i;
	}

	private short _baseCon = 0; // ● ＣＯＮベース（1～127）

	public short getBaseCon() {
		return _baseCon;
	}

	public void addBaseCon(short i) {
		全屬性總和 += i;
		i += _baseCon;
		i = (short) Math.max(i, 1);
		i = (short) Math.min(i, 32767);
		addCon((short) (i - _baseCon));
		_baseCon = i;
	}

	private short _baseDex = 0; // ● ＤＥＸベース（1～127）

	public short getBaseDex() {
		return _baseDex;
	}

	public void addBaseDex(short i) {
		全屬性總和 += i;
		i += _baseDex;
		i = (short) Math.max(i, 1);
		i = (short) Math.min(i, 32767);
		addDex((short) (i - _baseDex));
		_baseDex = i;
	}

	private short _baseCha = 0; // ● ＣＨＡベース（1～127）

	public short getBaseCha() {
		return _baseCha;
	}

	public void addBaseCha(short i) {
		全屬性總和 += i;
		i += _baseCha;
		i = (short) Math.max(i, 1);
		i = (short) Math.min(i, 32767);
		addCha((short) (i - _baseCha));
		_baseCha = i;
	}

	private short _baseInt = 0; // ● ＩＮＴベース（1～127）

	public short getBaseInt() {
		return _baseInt;
	}

	public void addBaseInt(short i) {
		全屬性總和 += i;
		i += _baseInt;
		i = (short) Math.max(i, 1);
		i = (short) Math.min(i, 32767);
		addInt((short) (i - _baseInt));
		_baseInt = i;
	}

	private short _baseWis = 0; // ● ＷＩＳベース（1～127）

	public short getBaseWis() {
		return _baseWis;
	}

	public void addBaseWis(short i) {
		全屬性總和 += i;
		i += _baseWis;
		i = (short) Math.max(i, 1);
		i = (short) Math.min(i, 32767);
		addWis((short) (i - _baseWis));
		_baseWis = i;
	}

	// opqlo 七屬性破127

	private int _originalStr = 0; // ● オリジナル STR

	public int getOriginalStr() {
		return _originalStr;
	}

	public void setOriginalStr(final int i) {
		_originalStr = i;
	}

	private int _originalCon = 0; // ● オリジナル CON

	public int getOriginalCon() {
		return _originalCon;
	}

	public void setOriginalCon(final int i) {
		_originalCon = i;
	}

	private int _originalDex = 0; // ● オリジナル DEX

	public int getOriginalDex() {
		return _originalDex;
	}

	public void setOriginalDex(final int i) {
		_originalDex = i;
	}

	private int _originalCha = 0; // ● オリジナル CHA

	public int getOriginalCha() {
		return _originalCha;
	}

	public void setOriginalCha(final int i) {
		_originalCha = i;
	}

	private int _originalInt = 0; // ● オリジナル INT

	public int getOriginalInt() {
		return _originalInt;
	}

	public void setOriginalInt(final int i) {
		_originalInt = i;
	}

	private int _originalWis = 0; // ● オリジナル WIS

	public int getOriginalWis() {
		return _originalWis;
	}

	public void setOriginalWis(final int i) {
		_originalWis = i;
	}

	private int _originalDmgup = 0; // ● オリジナルSTR ダメージ補正

	public int getOriginalDmgup() {

		return _originalDmgup;
	}

	private int _originalBowDmgup = 0; // ● オリジナルDEX 弓ダメージ補正

	public int getOriginalBowDmgup() {

		return _originalBowDmgup;
	}

	private int _originalHitup = 0; // ● オリジナルSTR 命中補正

	public int getOriginalHitup() {

		return _originalHitup;
	}

	public int _originalBowHitup = 0; // ● オリジナルDEX 命中補正

	public int getOriginalBowHitup() {

		return _originalHitup;
	}

	private int _originalMr = 0; // ● オリジナルWIS 魔法防御

	public int getOriginalMr() {

		return _originalMr;
	}

	private int _originalMagicHit = 0; // ● オリジナルINT 魔法命中

	public int getOriginalMagicHit() {

		return _originalMagicHit;
	}

	private int _originalMagicCritical = 0; // ● オリジナルINT 魔法クリティカル

	public int getOriginalMagicCritical() {

		return _originalMagicCritical;
	}

	private int _originalMagicConsumeReduction = 0; // ● オリジナルINT 消費MP軽減

	public int getOriginalMagicConsumeReduction() {

		return _originalMagicConsumeReduction;
	}

	private int _originalMagicDamage = 0; // ● オリジナルINT 魔法ダメージ

	public int getOriginalMagicDamage() {

		return _originalMagicDamage;
	}

	private int _originalHpup = 0; // ● オリジナルCON HP上昇値補正

	public int getOriginalHpup() {

		return _originalHpup;
	}

	private int _originalMpup = 0; // ● オリジナルWIS MP上昇値補正

	public int getOriginalMpup() {

		return _originalMpup;
	}

	private int _baseDmgup = 0; // ● ダメージ補正ベース（-128～127）

	public int getBaseDmgup() {
		return _baseDmgup;
	}

	private int _baseBowDmgup = 0; // ● 弓ダメージ補正ベース（-128～127）

	public int getBaseBowDmgup() {
		return _baseBowDmgup;
	}

	private int _baseHitup = 0; // ● 命中補正ベース（-128～127）

	public int getBaseHitup() {
		return _baseHitup;
	}

	private int _baseBowHitup = 0; // ● 弓命中補正ベース（-128～127）

	public int getBaseBowHitup() {
		return _baseBowHitup;
	}

	private int _baseMr = 0; // ● 魔法防御ベース（0～）

	public int getBaseMr() {
		return _baseMr;
	}

	private int _advenHp; // ● // アドバンスド スピリッツで増加しているＨＰ

	public int getAdvenHp() {
		return _advenHp;
	}

	public void setAdvenHp(final int i) {
		_advenHp = i;
	}

	private int _advenMp; // ● // アドバンスド スピリッツで増加しているＭＰ

	public int getAdvenMp() {
		return _advenMp;
	}

	public void setAdvenMp(final int i) {
		_advenMp = i;
	}

	private int _highLevel; // ● 過去最高レベル

	public int getHighLevel() {
		return _highLevel;
	}

	public void setHighLevel(final int i) {
		_highLevel = i;
	}

	private int _bonusStats; // ● 割り振ったボーナスステータス

	public int getBonusStats() {
		return _bonusStats;
	}

	public void setBonusStats(final int i) {
		_bonusStats = i;
	}

	private int _elixirStats; // ● エリクサーで上がったステータス

	public int getElixirStats() {
		return _elixirStats;
	}

	public void setElixirStats(final int i) {
		_elixirStats = i;
	}

	private int _elfAttr; // ● エルフの属性

	public int getElfAttr() {
		return _elfAttr;
	}

	public void setElfAttr(final int i) {
		_elfAttr = i;
	}

	private int _expRes; // ● EXP復旧

	public int getExpRes() {
		return _expRes;
	}

	public void setExpRes(final int i) {
		_expRes = i;
	}

	private int _partnerId; // ● 結婚相手

	public int getPartnerId() {
		return _partnerId;
	}

	public void setPartnerId(final int i) {
		_partnerId = i;
	}

	private int _onlineStatus; // ● オンライン状態

	public int getOnlineStatus() {
		return _onlineStatus;
	}

	public void setOnlineStatus(final int i) {
		_onlineStatus = i;
	}

	private int _homeTownId; // ● ホームタウン

	public int getHomeTownId() {
		return _homeTownId;
	}

	public void setHomeTownId(final int i) {
		_homeTownId = i;
	}

	private int _contribution; // ● 貢献度

	public int getContribution() {
		return _contribution;
	}

	public void setContribution(final int i) {
		_contribution = i;
	}

	// 地獄に滞在する時間（秒）
	private int _hellTime;

	public int getHellTime() {
		return _hellTime;
	}

	public void setHellTime(final int i) {
		_hellTime = i;
	}

	private boolean _banned; // ● 凍結

	public boolean isBanned() {
		return _banned;
	}

	public void setBanned(final boolean flag) {
		_banned = flag;
	}

	private int _food; // ● 満腹度

	public int get_food() {
		return _food;
	}

	public void set_food(final int i) {
		_food = i;
		if (_food >= 225) {// TODO 生存吶喊
			final Calendar cal = Calendar.getInstance();
			final long h_time = cal.getTimeInMillis() / 1000;// TODO 換算為秒
			set_h_time(h_time);// TODO 紀錄吃飽時間

		} else {
			set_h_time(-1);// TODO 紀錄吃飽時間
		}
	}

	public L1EquipmentSlot getEquipSlot() {
		return _equipSlot;
	}

	/**
	 * 加載指定PC資料
	 * 
	 * @param charName
	 *            PC名稱
	 * @return
	 */
	public static L1PcInstance load(final String charName) {
		L1PcInstance result = null;
		try {
			result = CharacterTable.getInstance().loadCharacter(charName);
		} catch (Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
		}
		return result;
	}

	/**
	 * このプレイヤーの状態をストレージへ書き込む。
	 * 
	 * @throws Exception
	 */
	public void save() throws Exception {
		if (isGhost()) {
			System.out.println("儲存角色失敗:" + isGhost());
			return;
		}
		if (isInCharReset()) {
			System.out.println("儲存角色失敗:" + isInCharReset());
			return;
		}

		CharacterTable.getInstance().storeCharacter(this);
	}

	// TODO 殷海薩的祝福
	private Timestamp _lastActive;

	public Timestamp getLastActive() {
		return _lastActive;
	}

	public void setLastActive(final Timestamp time) {
		_lastActive = time;
	}

	public void setLastActive() {
		_lastActive = new Timestamp(System.currentTimeMillis());
	}

	private int _ainZone = 1;

	public void setAinZone(final int i) {
		_ainZone = i;
	}

	public int getAinZone() {
		return _ainZone;
	}

	private int _ainPoint = 0;

	public void setAinPoint(final int i) {
		_ainPoint = i;
	}

	public int getAinPoint() {
		return _ainPoint;
	}

	/**
	 * このプレイヤーのインベントリアイテムの状態をストレージへ書き込む。
	 */
	public void saveInventory() {
		for (final L1ItemInstance item : getInventory().getItems()) {
			getInventory().saveItem(item, item.getRecordingColumns());
		}
	}

	public double getMaxWeight() {
		int str = getStr();
		int con = getCon();
		double maxWeight = 150 * (Math.floor(0.6 * str + 0.4 * con + 1));

		double weightReductionByArmor = getWeightReduction(); // 防具による重量軽減
		weightReductionByArmor /= 100;

		double weightReductionByDoll = 0; // マジックドールによる重量軽減

			// TODO 魔法娃娃DB化
			weightReductionByDoll += _dollList.getWeightReduction();
			// TODO 魔法娃娃DB化

		weightReductionByDoll /= 100;

		int weightReductionByMagic = 0;
		if (hasSkillEffect(DECREASE_WEIGHT)) { // ディクリースウェイト
			weightReductionByMagic = 180;
		}

		double originalWeightReduction = 0; // オリジナルステータスによる重量軽減
		originalWeightReduction += 0.04 * (getOriginalStrWeightReduction() + getOriginalConWeightReduction());

		double weightReduction = 1 + weightReductionByArmor
				+ weightReductionByDoll + originalWeightReduction;

		maxWeight *= weightReduction;

		maxWeight += weightReductionByMagic;

		maxWeight *= Config.RATE_WEIGHT_LIMIT; // ウェイトレートを掛ける

		return maxWeight;
	}

	public boolean isFastMovable() {
		return (hasSkillEffect(HOLY_WALK)
				|| hasSkillEffect(MOVING_ACCELERATION)
				|| hasSkillEffect(WIND_WALK) || hasSkillEffect(STATUS_RIBRAVE) || isThirdSpeed() > 1
				// TODO 三段加速
				/*
				 * || hasSkillEffect(STATUS_THIRD_SPEED2) ||
				 * hasSkillEffect(STATUS_THIRD_SPEED3) ||
				 * hasSkillEffect(STATUS_THIRD_SPEED4)
				 */);
		// TODO 三段加速
	}

	private boolean _isSpeedUp;

	public boolean isSpeedUp() { // opqlo 三段加速(巧克力部分)
		return _isSpeedUp;
	}

	public void setSpeedUp(final boolean i) {
		_isSpeedUp = i;
	}

	public boolean isFastAttackable() {
		return hasSkillEffect(BLOODLUST);
	}

	public boolean isBrave() {
		return hasSkillEffect(STATUS_BRAVE) || getBraveSpeed() == 1;
	}

	public boolean isElfBrave() {
		return hasSkillEffect(STATUS_ELFBRAVE);
	}

	public boolean isHaste() {
		return (hasSkillEffect(STATUS_HASTE) || hasSkillEffect(HASTE)
				|| hasSkillEffect(GREATER_HASTE) || getMoveSpeed() == 1);
	}

	private int invisDelayCounter = 0;

	public boolean isInvisDelay() {
		return (invisDelayCounter > 0);
	}

	private Object _invisTimerMonitor = new Object();

	public void addInvisDelayCounter(final int counter) {
		synchronized (_invisTimerMonitor) {
			invisDelayCounter += counter;
		}
	}

	private static final long DELAY_INVIS = 5000L;

	public void beginInvisTimer() {
		addInvisDelayCounter(1);
		GeneralThreadPool.getInstance().pcSchedule(new L1PcInvisDelay(getId()),DELAY_INVIS);
	}

	public synchronized void addContribution(final int contribution) {
		_contribution += contribution;
	}

	public void beginGameTimeCarrier() {
		new L1GameTimeCarrier(this).start();
	}

	private boolean _ghost = false; // ゴースト

	public boolean isGhost() {
		return _ghost;
	}

	private void setGhost(final boolean flag) {
		_ghost = flag;
	}

	private int _ghostTime = -1; // 鬼魂狀態時間

	/**
	 * 鬼魂狀態時間
	 * 
	 * @return
	 */
	public int get_ghostTime() {
		return this._ghostTime;
	}

	/**
	 * 設置鬼魂狀態時間
	 * 
	 * @param ghostTime
	 */
	public void set_ghostTime(final int ghostTime) {
		this._ghostTime = ghostTime;
	}

	private boolean _ghostCanTalk = true; // 鬼魂狀態NPC對話允許

	/**
	 * 鬼魂狀態NPC對話允許
	 * 
	 * @return
	 */
	public boolean isGhostCanTalk() {
		return _ghostCanTalk;
	}

	/**
	 * 設置鬼魂狀態NPC對話允許
	 * 
	 * @param flag
	 */
	private void setGhostCanTalk(final boolean flag) {
		_ghostCanTalk = flag;
	}

	private boolean _isReserveGhost = false; // 準備鬼魂狀態解除

	/**
	 * 準備鬼魂狀態解除
	 * 
	 * @return
	 */
	public boolean isReserveGhost() {
		return _isReserveGhost;
	}

	/**
	 * 準備鬼魂狀態解除
	 * 
	 * @param flag
	 */
	private void setReserveGhost(final boolean flag) {
		_isReserveGhost = flag;
	}

	/**
	 * 鬼魂模式傳送
	 * 
	 * @param locx
	 * @param locy
	 * @param mapid
	 * @param canTalk
	 */
	public void beginGhost(final int locx, final int locy, final short mapid,
			final boolean canTalk) {
		beginGhost(locx, locy, mapid, canTalk, 0);
	}

	/**
	 * 鬼魂模式傳送
	 * 
	 * @param locx
	 * @param locy
	 * @param mapid
	 * @param canTalk
	 * @param sec
	 */
	public void beginGhost(final int locx, final int locy, final short mapid,
			final boolean canTalk, final int sec) {
		if (isGhost()) {
			return;
		}
		setGhost(true);
		_ghostSaveLocX = getX();
		_ghostSaveLocY = getY();
		_ghostSaveMapId = getMapId();
		_ghostSaveHeading = getHeading();
		setGhostCanTalk(canTalk);
		L1Teleport.teleport(this, locx, locy, mapid, 5, true);
		if (sec > 0) {
			if(Config.USE_L1J){
				_ghostFuture = GeneralThreadPool.getInstance().pcSchedule(new L1PcGhostMonitor(getId()), sec * 1000);
			}else{
				this.set_ghostTime(sec);
			}
		}
	}

	/**
	 * 離開鬼魂模式(傳送回出發點)
	 */
	public void makeReadyEndGhost() {
		setReserveGhost(true);
		L1Teleport.teleport(this, _ghostSaveLocX, _ghostSaveLocY,_ghostSaveMapId, _ghostSaveHeading, true);
	}

	public void endGhost() {
		setGhost(false);
		setGhostCanTalk(true);
		setReserveGhost(false);
	}

	private int _ghostSaveLocX = 0;
	private int _ghostSaveLocY = 0;
	private short _ghostSaveMapId = 0;
	private int _ghostSaveHeading = 0;

	@Override
	public void setPoisonEffect(final int effectId) {
		sendPackets(new S_Poison(getId(), effectId));

		if (!isGmInvis() && !isGhost() && !isInvisble()) {
			broadcastPacketAll(new S_Poison(getId(), effectId));
		}
		if (isGmInvis() || isGhost()) {
		} else if (isInvisble()) {
			broadcastPacketForFindInvis(new S_Poison(getId(), effectId), true);
		} else {
			broadcastPacketAll(new S_Poison(getId(), effectId));
		}
	}

	@Override
	public void healHp(int pt) {
		super.healHp(pt);

		sendPackets(new S_HPUpdate(this));
	}

	@Override
	public int getKarma() {
		return _karma.get();
	}

	@Override
	public void setKarma(final int i) {
		_karma.set(i);
	}

	public void addKarma(final int i) {
		synchronized (_karma) {
			_karma.add(i);
		}
	}

	public int getKarmaLevel() {
		return _karma.getLevel();
	}

	public int getKarmaPercent() {
		return _karma.getPercent();
	}

	private Timestamp _lastPk;

	/**
	 * プレイヤーの最終PK時間を返す。
	 * 
	 * @return _lastPk
	 * 
	 */
	public Timestamp getLastPk() {
		return _lastPk;
	}

	/**
	 * プレイヤーの最終PK時間を設定する。
	 * 
	 * @param time
	 *            最終PK時間（Timestamp型） 解除する場合はnullを代入
	 */
	public void setLastPk(final Timestamp time) {
		_lastPk = time;
	}

	/**
	 * プレイヤーの最終PK時間を現在の時刻に設定する。
	 */
	public void setLastPk() {
		_lastPk = new Timestamp(System.currentTimeMillis());
	}

	/**
	 * 傳回玩家是否為通緝狀態(殺人後 2H) opqlo
	 * 
	 * @return 手配中であれば、true
	 */
	public boolean isWanted() {
		if (_lastPk == null) {
			return false;
			//		} else if (System.currentTimeMillis() - _lastPk.getTime() > 24 * 3600 * 1000) {
		} else if (System.currentTimeMillis() - _lastPk.getTime() > 7200000) {//2H
			setLastPk(null);
			return false;
		} else if (get_PKcount() <10){
			this.setLastPk(null);
			return false;
		}
		return true;
	}

	private Timestamp _lastPkForElf;

	public Timestamp getLastPkForElf() {
		return _lastPkForElf;
	}

	public void setLastPkForElf(final Timestamp time) {
		_lastPkForElf = time;
	}

	public void setLastPkForElf() {
		_lastPkForElf = new Timestamp(System.currentTimeMillis());
	}

	public boolean isWantedForElf() {
		if (_lastPkForElf == null) {
			return false;
		} else if (System.currentTimeMillis() - _lastPkForElf.getTime() > 24 * 3600 * 1000) {
			setLastPkForElf(null);
			return false;
		}
		return true;
	}

	@Override
	public int getMagicLevel() {
		return getClassFeature().getMagicLevel(getLevel());
	}

	private int _weightReduction = 0;

	public int getWeightReduction() {
		return _weightReduction;
	}

	public void addWeightReduction(final int i) {
		_weightReduction += i;
	}

	private int _originalStrWeightReduction = 0; // ● オリジナルSTR 重量軽減

	public int getOriginalStrWeightReduction() {

		return _originalStrWeightReduction;
	}

	private int _originalConWeightReduction = 0; // ● オリジナルCON 重量軽減

	public int getOriginalConWeightReduction() {

		return _originalConWeightReduction;
	}

	private int _hasteItemEquipped = 0;

	public int getHasteItemEquipped() {
		return _hasteItemEquipped;
	}

	public void addHasteItemEquipped(final int i) {
		_hasteItemEquipped += i;
	}

	public void removeHasteSkillEffect() {
		if (hasSkillEffect(SLOW)) {
			removeSkillEffect(SLOW);
		}
		if (hasSkillEffect(MASS_SLOW)) {
			removeSkillEffect(MASS_SLOW);
		}
		if (hasSkillEffect(ENTANGLE)) {
			removeSkillEffect(ENTANGLE);
		}
		if (hasSkillEffect(HASTE)) {
			removeSkillEffect(HASTE);
		}
		if (hasSkillEffect(GREATER_HASTE)) {
			removeSkillEffect(GREATER_HASTE);
		}
		if (hasSkillEffect(STATUS_HASTE)) {
			removeSkillEffect(STATUS_HASTE);
		}
		if (hasSkillEffect(STATUS_THIRD_SPEED)) {
			removeSkillEffect(STATUS_THIRD_SPEED);
		}
	}

	private int _damageReductionByArmor = 0; // 防具によるダメージ軽減

	public int getDamageReductionByArmor() {
		return _damageReductionByArmor + _CastleDmgReduction;
	}

	public void addDamageReductionByArmor(final int i) {
		_damageReductionByArmor += i;
	}

	private int _hitModifierByArmor = 0; // 防具による命中率補正

	public int getHitModifierByArmor() {
		return _hitModifierByArmor;
	}

	public void addHitModifierByArmor(final int i) {
		_hitModifierByArmor += i;
	}

	private int _dmgModifierByArmor = 0; // 防具によるダメージ補正

	public int getDmgModifierByArmor() {
		return _dmgModifierByArmor;
	}

	public void addDmgModifierByArmor(final int i) {
		_dmgModifierByArmor += i;
	}

	private int _bowHitModifierByArmor = 0; // 防具による弓の命中率補正

	public int getBowHitModifierByArmor() {
		return _bowHitModifierByArmor;
	}

	public void addBowHitModifierByArmor(final int i) {
		_bowHitModifierByArmor += i;
	}

	private int _bowDmgModifierByArmor = 0; // 防具による弓のダメージ補正

	public int getBowDmgModifierByArmor() {
		return _bowDmgModifierByArmor;
	}

	public void addBowDmgModifierByArmor(final int i) {
		_bowDmgModifierByArmor += i;
	}

	private boolean _gresValid; // G-RESが有効か

	public void setGresValid(final boolean valid) {
		_gresValid = valid;
	}

	public boolean isGresValid() {
		return _gresValid;
	}

	private long _fishingTime = 0;

	public long getFishingTime() {
		return _fishingTime;
	}

	public void setFishingTime(final long i) {
		_fishingTime = i;
	}

	private boolean _isFishing = false;

	public boolean isFishing() {
		return _isFishing;
	}

	public void setFishing(final boolean flag) {
		_isFishing = flag;
	}

	private boolean _isFishingReady = false;

	public boolean isFishingReady() {
		return _isFishingReady;
	}

	public void setFishingReady(final boolean flag) {
		_isFishingReady = flag;
	}

	private int _cookingId = 0;

	public int getCookingId() {
		return _cookingId;
	}

	public void setCookingId(final int i) {
		_cookingId = i;
	}

	private int _dessertId = 0;

	public int getDessertId() {
		return _dessertId;
	}

	public void setDessertId(final int i) {
		_dessertId = i;
	}

	/**
	 * LVによる命中ボーナスを設定する LVが変動した場合などに呼び出せば再計算される
	 * 
	 * @return
	 */
	public void resetBaseDmgup() {
		int newBaseDmgup = 0;
		int newBaseBowDmgup = 0;
		if (isKnight() || isDarkelf() || isDragonKnight()) { // ナイト、ダークエルフ、ドラゴンナイト
			newBaseDmgup = getLevel() / 10;
			newBaseBowDmgup = 0;
		} else if (isElf()) { // エルフ
			newBaseDmgup = 0;
			newBaseBowDmgup = getLevel() / 10;
		}
		addDmgup(newBaseDmgup - _baseDmgup);
		addBowDmgup(newBaseBowDmgup - _baseBowDmgup);
		_baseDmgup = newBaseDmgup;
		_baseBowDmgup = newBaseBowDmgup;
	}

	/**
	 * LVによる命中ボーナスを設定する LVが変動した場合などに呼び出せば再計算される
	 * 
	 * @return
	 */
	public void resetBaseHitup() {
		int newBaseHitup = 0;
		int newBaseBowHitup = 0;
		if (isCrown()) { // プリ
			newBaseHitup = getLevel() / 5;
			newBaseBowHitup = getLevel() / 5;
		} else if (isKnight()) { // ナイト
			newBaseHitup = getLevel() / 3;
			newBaseBowHitup = getLevel() / 3;
		} else if (isElf()) { // エルフ
			newBaseHitup = getLevel() / 5;
			newBaseBowHitup = getLevel() / 5;
		} else if (isDarkelf()) { // ダークエルフ
			newBaseHitup = getLevel() / 3;
			newBaseBowHitup = getLevel() / 3;
		} else if (isDragonKnight()) { // ドラゴンナイト
			newBaseHitup = getLevel() / 3;
			newBaseBowHitup = getLevel() / 3;
		} else if (isIllusionist()) { // イリュージョニスト
			newBaseHitup = getLevel() / 5;
			newBaseBowHitup = getLevel() / 5;
		}
		addHitup(newBaseHitup - _baseHitup);
		addBowHitup(newBaseBowHitup - _baseBowHitup);
		_baseHitup = newBaseHitup;
		_baseBowHitup = newBaseBowHitup;
	}

	/**
	 * キャラクターステータスからACを再計算して設定する 初期設定時、LVUP,LVDown時などに呼び出す
	 */
	public void resetBaseAc() {
		final int newAc = CalcStat.calcAc(getLevel(), getBaseDex());
		addAc(newAc - _baseAc);
		_baseAc = newAc;
	}

	/**
	 * 轉生行為 opqlo
	 */
	public void levelmetset() {
		_exp = 1;
		setLevel(ExpTable.getLevelByExp(_exp));

		final int newAc = CalcStat.calcAc(getLevel(), getBaseDex());
		addAc(newAc - _baseAc);
		_baseAc = newAc;
		int newMr = 0;
		int newBaseHitup = 0;
		int newBaseBowHitup = 0;
		int newBaseDmgup = 0;
		int newBaseBowDmgup = 0;

		final int lv = getLevel();
		switch (getType()) {

		case 0:// 王子
			newMr = 10;
			newBaseHitup = lv / 5;
			newBaseBowHitup = lv / 5;
			break;
		case 1:// 騎士
			newBaseHitup = lv / 3;
			newBaseBowHitup = lv / 3;
			newBaseDmgup = lv / 10;
			newBaseBowDmgup = 0;
			break;
		case 2:// 妖精
			newMr = 25;
			newBaseHitup = lv / 5;
			newBaseBowHitup = lv / 5;
			newBaseDmgup = 0;
			newBaseBowDmgup = lv / 10;
			break;
		case 3:// 法師
			newMr = 15;
			break;
		case 4:// 黑暗妖精
			newMr = 10;
			newBaseHitup = lv / 3;
			newBaseBowHitup = lv / 3;
			newBaseDmgup = lv / 10;
			newBaseBowDmgup = 0;
			break;
		case 5:// 龍騎士
			newMr = 18;
			newBaseHitup = lv / 3;
			newBaseBowHitup = lv / 3;
			newBaseDmgup = lv / 10;
			newBaseBowDmgup = 0;
			break;
		case 6:// 幻術士
			newMr = 20;
			newBaseHitup = lv / 5;
			newBaseBowHitup = lv / 5;
			break;
		}
		newMr += CalcStat.calcStatMr(getWis()); // WIS分のMRボーナス
		newMr += getLevel() / 2; // LVの半分だけ追加
		addMr(newMr - _baseMr);
		_baseMr = newMr;
		addHitup(newBaseHitup - _baseHitup);
		addBowHitup(newBaseBowHitup - _baseBowHitup);
		_baseHitup = newBaseHitup;
		_baseBowHitup = newBaseBowHitup;
		addDmgup(newBaseDmgup - _baseDmgup);
		addBowDmgup(newBaseBowDmgup - _baseBowDmgup);
		_baseDmgup = newBaseDmgup;
		_baseBowDmgup = newBaseBowDmgup;
		_bonusStats = 0;
		set_metempsychosis(get_metempsychosis() + 1);// TODO 轉生次數+1

	}

	/**
	 * キャラクターステータスから素のMRを再計算して設定する 初期設定時、スキル使用時やLVUP,LVDown時に呼び出す
	 */
	public void resetBaseMr() {
		int newMr = 0;
		if (isCrown()) { // プリ
			newMr = 10;
		} else if (isElf()) { // エルフ
			newMr = 25;
		} else if (isWizard()) { // ウィザード
			newMr = 15;
		} else if (isDarkelf()) { // ダークエルフ
			newMr = 10;
		} else if (isDragonKnight()) { // ドラゴンナイト
			newMr = 18;
		} else if (isIllusionist()) { // イリュージョニスト
			newMr = 20;
		}
		newMr += CalcStat.calcStatMr(getWis()); // WIS分のMRボーナス
		newMr += getLevel() / 2; // LVの半分だけ追加
		addMr(newMr - _baseMr);
		_baseMr = newMr;
	}

	/**
	 * EXPから現在のLvを再計算して設定する 初期設定時、死亡時やLVUP時に呼び出す
	 */
	public void resetLevel() {
		setLevel(ExpTable.getLevelByExp(_exp));
	}

	/**
	 * 初期ステータスから現在のボーナスを再計算して設定する 初期設定時、再配分時に呼び出す
	 */
	public void resetOriginalHpup() {
		final int originalCon = getOriginalCon();
		if (isCrown()) {
			if (originalCon == 12 || originalCon == 13) {
				_originalHpup = 1;
			} else if (originalCon == 14 || originalCon == 15) {
				_originalHpup = 2;
			} else if (originalCon >= 16) {
				_originalHpup = 3;
			} else {
				_originalHpup = 0;
			}
		} else if (isKnight()) {
			if (originalCon == 15 || originalCon == 16) {
				_originalHpup = 1;
			} else if (originalCon >= 17) {
				_originalHpup = 3;
			} else {
				_originalHpup = 0;
			}
		} else if (isElf()) {
			if (originalCon >= 13 && originalCon <= 17) {
				_originalHpup = 1;
			} else if (originalCon == 18) {
				_originalHpup = 2;
			} else {
				_originalHpup = 0;
			}
		} else if (isDarkelf()) {
			if (originalCon == 10 || originalCon == 11) {
				_originalHpup = 1;
			} else if (originalCon >= 12) {
				_originalHpup = 2;
			} else {
				_originalHpup = 0;
			}
		} else if (isWizard()) {
			if (originalCon == 14 || originalCon == 15) {
				_originalHpup = 1;
			} else if (originalCon >= 16) {
				_originalHpup = 2;
			} else {
				_originalHpup = 0;
			}
		} else if (isDragonKnight()) {
			if (originalCon == 15 || originalCon == 16) {
				_originalHpup = 1;
			} else if (originalCon >= 17) {
				_originalHpup = 3;
			} else {
				_originalHpup = 0;
			}
		} else if (isIllusionist()) {
			if (originalCon == 13 || originalCon == 14) {
				_originalHpup = 1;
			} else if (originalCon >= 15) {
				_originalHpup = 2;
			} else {
				_originalHpup = 0;
			}
		}
	}

	public void resetOriginalMpup() {
		final int originalWis = getOriginalWis();
		{
			if (isCrown()) {
				if (originalWis >= 16) {
					_originalMpup = 1;
				} else {
					_originalMpup = 0;
				}
			} else if (isKnight()) {
				_originalMpup = 0;
			} else if (isElf()) {
				if (originalWis >= 14 && originalWis <= 16) {
					_originalMpup = 1;
				} else if (originalWis >= 17) {
					_originalMpup = 2;
				} else {
					_originalMpup = 0;
				}
			} else if (isDarkelf()) {
				if (originalWis >= 12) {
					_originalMpup = 1;
				} else {
					_originalMpup = 0;
				}
			} else if (isWizard()) {
				if (originalWis >= 13 && originalWis <= 16) {
					_originalMpup = 1;
				} else if (originalWis >= 17) {
					_originalMpup = 2;
				} else {
					_originalMpup = 0;
				}
			} else if (isDragonKnight()) {
				if (originalWis >= 13 && originalWis <= 15) {
					_originalMpup = 1;
				} else if (originalWis >= 16) {
					_originalMpup = 2;
				} else {
					_originalMpup = 0;
				}
			} else if (isIllusionist()) {
				if (originalWis >= 13 && originalWis <= 15) {
					_originalMpup = 1;
				} else if (originalWis >= 16) {
					_originalMpup = 2;
				} else {
					_originalMpup = 0;
				}
			}
		}
	}

	public void resetOriginalStrWeightReduction() {
		final int originalStr = getOriginalStr();
		if (isCrown()) {
			if (originalStr >= 14 && originalStr <= 16) {
				_originalStrWeightReduction = 1;
			} else if (originalStr >= 17 && originalStr <= 19) {
				_originalStrWeightReduction = 2;
			} else if (originalStr == 20) {
				_originalStrWeightReduction = 3;
			} else {
				_originalStrWeightReduction = 0;
			}
		} else if (isKnight()) {
			_originalStrWeightReduction = 0;
		} else if (isElf()) {
			if (originalStr >= 16) {
				_originalStrWeightReduction = 2;
			} else {
				_originalStrWeightReduction = 0;
			}
		} else if (isDarkelf()) {
			if (originalStr >= 13 && originalStr <= 15) {
				_originalStrWeightReduction = 2;
			} else if (originalStr >= 16) {
				_originalStrWeightReduction = 3;
			} else {
				_originalStrWeightReduction = 0;
			}
		} else if (isWizard()) {
			if (originalStr >= 9) {
				_originalStrWeightReduction = 1;
			} else {
				_originalStrWeightReduction = 0;
			}
		} else if (isDragonKnight()) {
			if (originalStr >= 16) {
				_originalStrWeightReduction = 1;
			} else {
				_originalStrWeightReduction = 0;
			}
		} else if (isIllusionist()) {
			if (originalStr == 18) {
				_originalStrWeightReduction = 1;
			} else {
				_originalStrWeightReduction = 0;
			}
		}
	}

	public void resetOriginalDmgup() {
		final int originalStr = getOriginalStr();
		if (isCrown()) {
			if (originalStr >= 15 && originalStr <= 17) {
				_originalDmgup = 1;
			} else if (originalStr >= 18) {
				_originalDmgup = 2;
			} else {
				_originalDmgup = 0;
			}
		} else if (isKnight()) {
			if (originalStr == 18 || originalStr == 19) {
				_originalDmgup = 2;
			} else if (originalStr == 20) {
				_originalDmgup = 4;
			} else {
				_originalDmgup = 0;
			}
		} else if (isElf()) {
			if (originalStr == 12 || originalStr == 13) {
				_originalDmgup = 1;
			} else if (originalStr >= 14) {
				_originalDmgup = 2;
			} else {
				_originalDmgup = 0;
			}
		} else if (isDarkelf()) {
			if (originalStr >= 14 && originalStr <= 17) {
				_originalDmgup = 1;
			} else if (originalStr == 18) {
				_originalDmgup = 2;
			} else {
				_originalDmgup = 0;
			}
		} else if (isWizard()) {
			if (originalStr == 10 || originalStr == 11) {
				_originalDmgup = 1;
			} else if (originalStr >= 12) {
				_originalDmgup = 2;
			} else {
				_originalDmgup = 0;
			}
		} else if (isDragonKnight()) {
			if (originalStr >= 15 && originalStr <= 17) {
				_originalDmgup = 1;
			} else if (originalStr >= 18) {
				_originalDmgup = 3;
			} else {
				_originalDmgup = 0;
			}
		} else if (isIllusionist()) {
			if (originalStr == 13 || originalStr == 14) {
				_originalDmgup = 1;
			} else if (originalStr >= 15) {
				_originalDmgup = 2;
			} else {
				_originalDmgup = 0;
			}
		}
	}

	public void resetOriginalConWeightReduction() {
		final int originalCon = getOriginalCon();
		if (isCrown()) {
			if (originalCon >= 11) {
				_originalConWeightReduction = 1;
			} else {
				_originalConWeightReduction = 0;
			}
		} else if (isKnight()) {
			if (originalCon >= 15) {
				_originalConWeightReduction = 1;
			} else {
				_originalConWeightReduction = 0;
			}
		} else if (isElf()) {
			if (originalCon >= 15) {
				_originalConWeightReduction = 2;
			} else {
				_originalConWeightReduction = 0;
			}
		} else if (isDarkelf()) {
			if (originalCon >= 9) {
				_originalConWeightReduction = 1;
			} else {
				_originalConWeightReduction = 0;
			}
		} else if (isWizard()) {
			if (originalCon == 13 || originalCon == 14) {
				_originalConWeightReduction = 1;
			} else if (originalCon >= 15) {
				_originalConWeightReduction = 2;
			} else {
				_originalConWeightReduction = 0;
			}
		} else if (isDragonKnight()) {
			_originalConWeightReduction = 0;
		} else if (isIllusionist()) {
			if (originalCon == 17) {
				_originalConWeightReduction = 1;
			} else if (originalCon == 18) {
				_originalConWeightReduction = 2;
			} else {
				_originalConWeightReduction = 0;
			}
		}
	}

	public void resetOriginalBowDmgup() {
		final int originalDex = getOriginalDex();
		if (isCrown()) {
			if (originalDex >= 13) {
				_originalBowDmgup = 1;
			} else {
				_originalBowDmgup = 0;
			}
		} else if (isKnight()) {
			_originalBowDmgup = 0;
		} else if (isElf()) {
			if (originalDex >= 14 && originalDex <= 16) {
				_originalBowDmgup = 2;
			} else if (originalDex >= 17) {
				_originalBowDmgup = 3;
			} else {
				_originalBowDmgup = 0;
			}
		} else if (isDarkelf()) {
			if (originalDex == 18) {
				_originalBowDmgup = 2;
			} else {
				_originalBowDmgup = 0;
			}
		} else if (isWizard()) {
			_originalBowDmgup = 0;
		} else if (isDragonKnight()) {
			_originalBowDmgup = 0;
		} else if (isIllusionist()) {
			_originalBowDmgup = 0;
		}
	}

	public void resetOriginalHitup() {
		final int originalStr = getOriginalStr();
		if (isCrown()) {
			if (originalStr >= 16 && originalStr <= 18) {
				_originalHitup = 1;
			} else if (originalStr >= 19) {
				_originalHitup = 2;
			} else {
				_originalHitup = 0;
			}
		} else if (isKnight()) {
			if (originalStr == 17 || originalStr == 18) {
				_originalHitup = 2;
			} else if (originalStr >= 19) {
				_originalHitup = 4;
			} else {
				_originalHitup = 0;
			}
		} else if (isElf()) {
			if (originalStr == 13 || originalStr == 14) {
				_originalHitup = 1;
			} else if (originalStr >= 15) {
				_originalHitup = 2;
			} else {
				_originalHitup = 0;
			}
		} else if (isDarkelf()) {
			if (originalStr >= 15 && originalStr <= 17) {
				_originalHitup = 1;
			} else if (originalStr == 18) {
				_originalHitup = 2;
			} else {
				_originalHitup = 0;
			}
		} else if (isWizard()) {
			if (originalStr == 11 || originalStr == 12) {
				_originalHitup = 1;
			} else if (originalStr >= 13) {
				_originalHitup = 2;
			} else {
				_originalHitup = 0;
			}
		} else if (isDragonKnight()) {
			if (originalStr >= 14 && originalStr <= 16) {
				_originalHitup = 1;
			} else if (originalStr >= 17) {
				_originalHitup = 3;
			} else {
				_originalHitup = 0;
			}
		} else if (isIllusionist()) {
			if (originalStr == 12 || originalStr == 13) {
				_originalHitup = 1;
			} else if (originalStr == 14 || originalStr == 15) {
				_originalHitup = 2;
			} else if (originalStr == 16) {
				_originalHitup = 3;
			} else if (originalStr >= 17) {
				_originalHitup = 4;
			} else {
				_originalHitup = 0;
			}
		}
	}

	public void resetOriginalBowHitup() {
		final int originalDex = getOriginalDex();
		if (isCrown()) {
			_originalBowHitup = 0;
		} else if (isKnight()) {
			_originalBowHitup = 0;
		} else if (isElf()) {
			if (originalDex >= 13 && originalDex <= 15) {
				_originalBowHitup = 2;
			} else if (originalDex >= 16) {
				_originalBowHitup = 3;
			} else {
				_originalBowHitup = 0;
			}
		} else if (isDarkelf()) {
			if (originalDex == 17) {
				_originalBowHitup = 1;
			} else if (originalDex == 18) {
				_originalBowHitup = 2;
			} else {
				_originalBowHitup = 0;
			}
		} else if (isWizard()) {
			_originalBowHitup = 0;
		} else if (isDragonKnight()) {
			_originalBowHitup = 0;
		} else if (isIllusionist()) {
			_originalBowHitup = 0;
		}
	}

	public void resetOriginalMr() {
		final int originalWis = getOriginalWis();
		if (isCrown()) {
			if (originalWis == 12 || originalWis == 13) {
				_originalMr = 1;
			} else if (originalWis >= 14) {
				_originalMr = 2;
			} else {
				_originalMr = 0;
			}
		} else if (isKnight()) {
			if (originalWis == 10 || originalWis == 11) {
				_originalMr = 1;
			} else if (originalWis >= 12) {
				_originalMr = 2;
			} else {
				_originalMr = 0;
			}
		} else if (isElf()) {
			if (originalWis >= 13 && originalWis <= 15) {
				_originalMr = 1;
			} else if (originalWis >= 16) {
				_originalMr = 2;
			} else {
				_originalMr = 0;
			}
		} else if (isDarkelf()) {
			if (originalWis >= 11 && originalWis <= 13) {
				_originalMr = 1;
			} else if (originalWis == 14) {
				_originalMr = 2;
			} else if (originalWis == 15) {
				_originalMr = 3;
			} else if (originalWis >= 16) {
				_originalMr = 4;
			} else {
				_originalMr = 0;
			}
		} else if (isWizard()) {
			if (originalWis >= 15) {
				_originalMr = 1;
			} else {
				_originalMr = 0;
			}
		} else if (isDragonKnight()) {
			if (originalWis >= 14) {
				_originalMr = 2;
			} else {
				_originalMr = 0;
			}
		} else if (isIllusionist()) {
			if (originalWis >= 15 && originalWis <= 17) {
				_originalMr = 2;
			} else if (originalWis == 18) {
				_originalMr = 4;
			} else {
				_originalMr = 0;
			}
		}

		addMr(_originalMr);
	}

	public void resetOriginalMagicHit() {
		final int originalInt = getOriginalInt();
		if (isCrown()) {
			if (originalInt == 12 || originalInt == 13) {
				_originalMagicHit = 1;
			} else if (originalInt >= 14) {
				_originalMagicHit = 2;
			} else {
				_originalMagicHit = 0;
			}
		} else if (isKnight()) {
			if (originalInt == 10 || originalInt == 11) {
				_originalMagicHit = 1;
			} else if (originalInt == 12) {
				_originalMagicHit = 2;
			} else {
				_originalMagicHit = 0;
			}
		} else if (isElf()) {
			if (originalInt == 13 || originalInt == 14) {
				_originalMagicHit = 1;
			} else if (originalInt >= 15) {
				_originalMagicHit = 2;
			} else {
				_originalMagicHit = 0;
			}
		} else if (isDarkelf()) {
			if (originalInt == 12 || originalInt == 13) {
				_originalMagicHit = 1;
			} else if (originalInt >= 14) {
				_originalMagicHit = 2;
			} else {
				_originalMagicHit = 0;
			}
		} else if (isWizard()) {
			if (originalInt >= 14) {
				_originalMagicHit = 1;
			} else {
				_originalMagicHit = 0;
			}
		} else if (isDragonKnight()) {
			if (originalInt == 12 || originalInt == 13) {
				_originalMagicHit = 2;
			} else if (originalInt == 14 || originalInt == 15) {
				_originalMagicHit = 3;
			} else if (originalInt >= 16) {
				_originalMagicHit = 4;
			} else {
				_originalMagicHit = 0;
			}
		} else if (isIllusionist()) {
			if (originalInt >= 13) {
				_originalMagicHit = 1;
			} else {
				_originalMagicHit = 0;
			}
		}
	}

	public void resetOriginalMagicCritical() {
		final int originalInt = getOriginalInt();
		if (isCrown()) {
			_originalMagicCritical = 0;
		} else if (isKnight()) {
			_originalMagicCritical = 0;
		} else if (isElf()) {
			if (originalInt == 14 || originalInt == 15) {
				_originalMagicCritical = 2;
			} else if (originalInt >= 16) {
				_originalMagicCritical = 4;
			} else {
				_originalMagicCritical = 0;
			}
		} else if (isDarkelf()) {
			_originalMagicCritical = 0;
		} else if (isWizard()) {
			if (originalInt == 15) {
				_originalMagicCritical = 2;
			} else if (originalInt == 16) {
				_originalMagicCritical = 4;
			} else if (originalInt == 17) {
				_originalMagicCritical = 6;
			} else if (originalInt == 18) {
				_originalMagicCritical = 8;
			} else {
				_originalMagicCritical = 0;
			}
		} else if (isDragonKnight()) {
			_originalMagicCritical = 0;
		} else if (isIllusionist()) {
			_originalMagicCritical = 0;
		}
	}

	public void resetOriginalMagicConsumeReduction() {
		final int originalInt = getOriginalInt();
		if (isCrown()) {
			if (originalInt == 11 || originalInt == 12) {
				_originalMagicConsumeReduction = 1;
			} else if (originalInt >= 13) {
				_originalMagicConsumeReduction = 2;
			} else {
				_originalMagicConsumeReduction = 0;
			}
		} else if (isKnight()) {
			if (originalInt == 9 || originalInt == 10) {
				_originalMagicConsumeReduction = 1;
			} else if (originalInt >= 11) {
				_originalMagicConsumeReduction = 2;
			} else {
				_originalMagicConsumeReduction = 0;
			}
		} else if (isElf()) {
			_originalMagicConsumeReduction = 0;
		} else if (isDarkelf()) {
			if (originalInt == 13 || originalInt == 14) {
				_originalMagicConsumeReduction = 1;
			} else if (originalInt >= 15) {
				_originalMagicConsumeReduction = 2;
			} else {
				_originalMagicConsumeReduction = 0;
			}
		} else if (isWizard()) {
			_originalMagicConsumeReduction = 0;
		} else if (isDragonKnight()) {
			_originalMagicConsumeReduction = 0;
		} else if (isIllusionist()) {
			if (originalInt == 14) {
				_originalMagicConsumeReduction = 1;
			} else if (originalInt >= 15) {
				_originalMagicConsumeReduction = 2;
			} else {
				_originalMagicConsumeReduction = 0;
			}
		}
	}

	public void resetOriginalMagicDamage() {
		final int originalInt = getOriginalInt();
		if (isCrown()) {
			_originalMagicDamage = 0;
		} else if (isKnight()) {
			_originalMagicDamage = 0;
		} else if (isElf()) {
			_originalMagicDamage = 0;
		} else if (isDarkelf()) {
			_originalMagicDamage = 0;
		} else if (isWizard()) {
			if (originalInt >= 13) {
				_originalMagicDamage = 1;
			} else {
				_originalMagicDamage = 0;
			}
		} else if (isDragonKnight()) {
			if (originalInt == 13 || originalInt == 14) {
				_originalMagicDamage = 1;
			} else if (originalInt == 15 || originalInt == 16) {
				_originalMagicDamage = 2;
			} else if (originalInt == 17) {
				_originalMagicDamage = 3;
			} else {
				_originalMagicDamage = 0;
			}
		} else if (isIllusionist()) {
			if (originalInt == 16) {
				_originalMagicDamage = 1;
			} else if (originalInt == 17) {
				_originalMagicDamage = 2;
			} else {
				_originalMagicDamage = 0;
			}
		}
	}

	public void resetOriginalAc() {
		final int originalDex = getOriginalDex();
		if (isCrown()) {
			if (originalDex >= 12 && originalDex <= 14) {
				_originalAc = 1;
			} else if (originalDex == 15 || originalDex == 16) {
				_originalAc = 2;
			} else if (originalDex >= 17) {
				_originalAc = 3;
			} else {
				_originalAc = 0;
			}
		} else if (isKnight()) {
			if (originalDex == 13 || originalDex == 14) {
				_originalAc = 1;
			} else if (originalDex >= 15) {
				_originalAc = 3;
			} else {
				_originalAc = 0;
			}
		} else if (isElf()) {
			if (originalDex >= 15 && originalDex <= 17) {
				_originalAc = 1;
			} else if (originalDex == 18) {
				_originalAc = 2;
			} else {
				_originalAc = 0;
			}
		} else if (isDarkelf()) {
			if (originalDex >= 17) {
				_originalAc = 1;
			} else {
				_originalAc = 0;
			}
		} else if (isWizard()) {
			if (originalDex == 8 || originalDex == 9) {
				_originalAc = 1;
			} else if (originalDex >= 10) {
				_originalAc = 2;
			} else {
				_originalAc = 0;
			}
		} else if (isDragonKnight()) {
			if (originalDex == 12 || originalDex == 13) {
				_originalAc = 1;
			} else if (originalDex >= 14) {
				_originalAc = 2;
			} else {
				_originalAc = 0;
			}
		} else if (isIllusionist()) {
			if (originalDex == 11 || originalDex == 12) {
				_originalAc = 1;
			} else if (originalDex >= 13) {
				_originalAc = 2;
			} else {
				_originalAc = 0;
			}
		}

		addAc(0 - _originalAc);
	}

	public void resetOriginalEr() {
		final int originalDex = getOriginalDex();
		if (isCrown()) {
			if (originalDex == 14 || originalDex == 15) {
				_originalEr = 1;
			} else if (originalDex == 16 || originalDex == 17) {
				_originalEr = 2;
			} else if (originalDex == 18) {
				_originalEr = 3;
			} else {
				_originalEr = 0;
			}
		} else if (isKnight()) {
			if (originalDex == 14 || originalDex == 15) {
				_originalEr = 1;
			} else if (originalDex == 16) {
				_originalEr = 3;
			} else {
				_originalEr = 0;
			}
		} else if (isElf()) {
			_originalEr = 0;
		} else if (isDarkelf()) {
			if (originalDex >= 16) {
				_originalEr = 2;
			} else {
				_originalEr = 0;
			}
		} else if (isWizard()) {
			if (originalDex == 9 || originalDex == 10) {
				_originalEr = 1;
			} else if (originalDex == 11) {
				_originalEr = 2;
			} else {
				_originalEr = 0;
			}
		} else if (isDragonKnight()) {
			if (originalDex == 13 || originalDex == 14) {
				_originalEr = 1;
			} else if (originalDex >= 15) {
				_originalEr = 2;
			} else {
				_originalEr = 0;
			}
		} else if (isIllusionist()) {
			if (originalDex == 12 || originalDex == 13) {
				_originalEr = 1;
			} else if (originalDex >= 14) {
				_originalEr = 2;
			} else {
				_originalEr = 0;
			}
		}
	}

	public void resetOriginalHpr() {
		final int originalCon = getOriginalCon();
		if (isCrown()) {
			if (originalCon == 13 || originalCon == 14) {
				_originalHpr = 1;
			} else if (originalCon == 15 || originalCon == 16) {
				_originalHpr = 2;
			} else if (originalCon == 17) {
				_originalHpr = 3;
			} else if (originalCon == 18) {
				_originalHpr = 4;
			} else {
				_originalHpr = 0;
			}
		} else if (isKnight()) {
			if (originalCon == 16 || originalCon == 17) {
				_originalHpr = 2;
			} else if (originalCon == 18) {
				_originalHpr = 4;
			} else {
				_originalHpr = 0;
			}
		} else if (isElf()) {
			if (originalCon == 14 || originalCon == 15) {
				_originalHpr = 1;
			} else if (originalCon == 16) {
				_originalHpr = 2;
			} else if (originalCon >= 17) {
				_originalHpr = 3;
			} else {
				_originalHpr = 0;
			}
		} else if (isDarkelf()) {
			if (originalCon == 11 || originalCon == 12) {
				_originalHpr = 1;
			} else if (originalCon >= 13) {
				_originalHpr = 2;
			} else {
				_originalHpr = 0;
			}
		} else if (isWizard()) {
			if (originalCon == 17) {
				_originalHpr = 1;
			} else if (originalCon == 18) {
				_originalHpr = 2;
			} else {
				_originalHpr = 0;
			}
		} else if (isDragonKnight()) {
			if (originalCon == 16 || originalCon == 17) {
				_originalHpr = 1;
			} else if (originalCon == 18) {
				_originalHpr = 3;
			} else {
				_originalHpr = 0;
			}
		} else if (isIllusionist()) {
			if (originalCon == 14 || originalCon == 15) {
				_originalHpr = 1;
			} else if (originalCon >= 16) {
				_originalHpr = 2;
			} else {
				_originalHpr = 0;
			}
		}
	}

	public void resetOriginalMpr() {
		final int originalWis = getOriginalWis();
		if (isCrown()) {
			if (originalWis == 13 || originalWis == 14) {
				_originalMpr = 1;
			} else if (originalWis >= 15) {
				_originalMpr = 2;
			} else {
				_originalMpr = 0;
			}
		} else if (isKnight()) {
			if (originalWis == 11 || originalWis == 12) {
				_originalMpr = 1;
			} else if (originalWis == 13) {
				_originalMpr = 2;
			} else {
				_originalMpr = 0;
			}
		} else if (isElf()) {
			if (originalWis >= 15 && originalWis <= 17) {
				_originalMpr = 1;
			} else if (originalWis == 18) {
				_originalMpr = 2;
			} else {
				_originalMpr = 0;
			}
		} else if (isDarkelf()) {
			if (originalWis >= 13) {
				_originalMpr = 1;
			} else {
				_originalMpr = 0;
			}
		} else if (isWizard()) {
			if (originalWis == 14 || originalWis == 15) {
				_originalMpr = 1;
			} else if (originalWis == 16 || originalWis == 17) {
				_originalMpr = 2;
			} else if (originalWis == 18) {
				_originalMpr = 3;
			} else {
				_originalMpr = 0;
			}
		} else if (isDragonKnight()) {
			if (originalWis == 15 || originalWis == 16) {
				_originalMpr = 1;
			} else if (originalWis >= 17) {
				_originalMpr = 2;
			} else {
				_originalMpr = 0;
			}
		} else if (isIllusionist()) {
			if (originalWis >= 14 && originalWis <= 16) {
				_originalMpr = 1;
			} else if (originalWis >= 17) {
				_originalMpr = 2;
			} else {
				_originalMpr = 0;
			}
		}
	}

	public void refresh() {
		resetLevel();
		resetBaseHitup();
		resetBaseDmgup();
		resetBaseMr();
		resetBaseAc();
		resetOriginalHpup();
		resetOriginalMpup();
		resetOriginalDmgup();
		resetOriginalBowDmgup();
		resetOriginalHitup();
		resetOriginalBowHitup();
		resetOriginalMr();
		resetOriginalMagicHit();
		resetOriginalMagicCritical();
		resetOriginalMagicConsumeReduction();
		resetOriginalMagicDamage();
		resetOriginalAc();
		resetOriginalEr();
		resetOriginalHpr();
		resetOriginalMpr();
		resetOriginalStrWeightReduction();
		resetOriginalConWeightReduction();
	}

	private L1PartyRefresh _rp;

	public void startRefreshParty() {// 組隊更新 3.3C
		final int INTERVAL = 5000;
		if (!_rpActive) {
			_rp = new L1PartyRefresh(this);
			_regenTimer.scheduleAtFixedRate(_rp, INTERVAL, INTERVAL);
			_rpActive = true;
		}
	}

	public void stopRefreshParty() {// 組隊暫停更新 3.3C
		if (_rpActive) {
			_rp.cancel();
			_rp = null;
			_rpActive = false;
		}
	}

	private L1ExcludingList _excludingList;

	public L1ExcludingList getExcludingList() {
		if(_excludingList == null){
			_excludingList =new L1ExcludingList();
		}
		return _excludingList;
	}


	// -- 加速器検知機能 --
	private final AcceleratorChecker _acceleratorChecker = new AcceleratorChecker(this);

	public AcceleratorChecker getAcceleratorChecker() {
		return _acceleratorChecker;
	}

	/**
	 * テレポート先の座標
	 */
	private int _teleportX = 0;

	public int getTeleportX() {
		return _teleportX;
	}

	public void setTeleportX(final int i) {
		_teleportX = i;
	}

	private int _teleportY = 0;

	public int getTeleportY() {
		return _teleportY;
	}

	public void setTeleportY(final int i) {
		_teleportY = i;
	}

	private short _teleportMapId = 0;

	public short getTeleportMapId() {
		return _teleportMapId;
	}

	public void setTeleportMapId(final short i) {
		_teleportMapId = i;
	}

	private int _teleportHeading = 0;

	public int getTeleportHeading() {
		return _teleportHeading;
	}

	public void setTeleportHeading( int i) {
		if(i > 7 || i < 0 ){
			i = 0;
		}
		_teleportHeading = i;
	}

	private int _tempCharGfxAtDead;

	public int getTempCharGfxAtDead() {
		return _tempCharGfxAtDead;
	}

	public void setTempCharGfxAtDead(final int i) {
		_tempCharGfxAtDead = i;
	}

	private boolean _isCanWhisper = true;

	public boolean isCanWhisper() {
		return _isCanWhisper;
	}

	public void setCanWhisper(final boolean flag) {
		_isCanWhisper = flag;
	}

	private boolean _isShowTradeChat = true;

	public boolean isShowTradeChat() {
		return _isShowTradeChat;
	}

	public void setShowTradeChat(final boolean flag) {
		_isShowTradeChat = flag;
	}

	// TODO 血盟
	private boolean _isShowClanChat = true;

	public boolean isShowClanChat() {
		return _isShowClanChat;
	}

	public void setShowClanChat(final boolean flag) {
		_isShowClanChat = flag;
	}

	// TODO 血盟

	// TODO 組隊
	private boolean _isShowPartyChat = true;

	public boolean isShowPartyChat() {
		return _isShowPartyChat;
	}

	// TODO 組隊

	public void setShowPartyChat(final boolean flag) {
		_isShowPartyChat = flag;
	}

	private boolean _isShowWorldChat = true;

	public boolean isShowWorldChat() {
		return _isShowWorldChat;
	}

	public void setShowWorldChat(final boolean flag) {
		_isShowWorldChat = flag;
	}

	private int _fightId;

	public int getFightId() {
		return _fightId;
	}

	public void setFightId(final int i) {
		_fightId = i;
	}

	private byte _chatCount = 0;

	private long _oldChatTimeInMillis = 0L;

	public void checkChatInterval() {
		final long nowChatTimeInMillis = System.currentTimeMillis();
		if (_chatCount == 0) {
			_chatCount++;
			_oldChatTimeInMillis = nowChatTimeInMillis;
			return;
		}

		final long chatInterval = nowChatTimeInMillis - _oldChatTimeInMillis;
		if (chatInterval > 2000) {
			_chatCount = 0;
			_oldChatTimeInMillis = 0;
		} else {
			if (_chatCount >= 3) {
				setSkillEffect(STATUS_CHAT_PROHIBITED, 120 * 1000);
				sendPackets(new S_SkillIconGFX(36, 120));
				sendPackets(new S_ServerMessage(153)); // \f3迷惑なチャット流しをしたので、今後2分間チャットを行うことはできません。
				_chatCount = 0;
				_oldChatTimeInMillis = 0;
			}
			_chatCount++;
		}
	}

	private int _callClanId;

	public int getCallClanId() {
		return _callClanId;
	}

	public void setCallClanId(final int i) {
		_callClanId = i;
	}

	private int _callClanHeading;

	public int getCallClanHeading() {
		return _callClanHeading;
	}

	public void setCallClanHeading(final int i) {
		_callClanHeading = i;
	}

	private boolean _isInCharReset = false;

	public boolean isInCharReset() {
		return _isInCharReset;
	}

	public void setInCharReset(final boolean flag) {
		_isInCharReset = flag;
	}

	private int _tempLevel = 1;

	public int getTempLevel() {
		return _tempLevel;
	}

	public void setTempLevel(final int i) {
		_tempLevel = i;
	}

	private int _tempMaxLevel = 1;

	public int getTempMaxLevel() {
		return _tempMaxLevel;
	}

	public void setTempMaxLevel(final int i) {
		_tempMaxLevel = i;
	}

	private int _awakeSkillId = 0;

	public int getAwakeSkillId() {
		return _awakeSkillId;
	}

	public void setAwakeSkillId(final int i) {
		_awakeSkillId = i;
	}

	private boolean _isSummonMonster = false;

	public void setSummonMonster(final boolean SummonMonster) {
		_isSummonMonster = SummonMonster;
	}

	public boolean isSummonMonster() {
		return _isSummonMonster;
	}

	private boolean _isShapeChange = false;

	public void setShapeChange(final boolean isShapeChange) {
		_isShapeChange = isShapeChange;
	}

	public boolean isShapeChange() {
		return _isShapeChange;
	}

	// TODO 套裝效果
	private l1j.william.SustainEffect SustainEffect;

	public void startSustainEffect(final L1PcInstance pc, final int effect_id,
			final int Interval) {
		final int _Interval = Interval;// TODO 間隔時間
		SustainEffect = new l1j.william.SustainEffect(pc, effect_id);
		_regenTimer.scheduleAtFixedRate(SustainEffect, _Interval, _Interval);
	}

	public void stopSustainEffect() {
		SustainEffect.cancel();
		SustainEffect = null;
	}

	// TODO 套裝效果

	// TODO 3.3組隊系統
	public void setPartyType(final int type) {
		_partyType = type;
	}

	// TODO 3.3組隊系統

	public int getPartyType() {
		return _partyType;
	}

	private int _old_lawful;


	public synchronized void addLawful(final int i) {
		int lawful = this.getLawful() + i;
		if (lawful > 32767) {
			lawful = 32767;

		} else if (lawful < -32768) {
			lawful = -32768;
		}
		this.setLawful(lawful);
		onChangeLawful();
	}
	/**
	 * 更新Lawful
	 */
	public void onChangeLawful() {
		if (_old_lawful != getLawful()) {
			_old_lawful = getLawful();
			sendPacketsAll(new S_Lawful(getId(), _old_lawful));
			// 戰鬥特化效果
			// TODO 處理戰鬥特化系統
			final int fightType = _old_lawful / 10000;
			if (_oldFight != fightType) {
				changeFightType(_oldFight, fightType);
				_oldFight = fightType;
			}
		}
		// TODO 處理戰鬥特化系統
		// TODO 友好度實裝
		if (_old_karma != getKarma()) {
			_old_karma = getKarma();
			sendPackets(new S_Karma(this));
		}
	}

	private int _old_karma;// TODO 友好度實裝

	private int _oldFight;// TODO 上一次判斷時的戰鬥特化類別

	// TODO 戰鬥特化系統
	public void changeFightType(final int oldType, final int newType) {
		// TODO 消除既有的戰鬥特化狀態
		switch (oldType) {
		case 1:
			addAc(2);
			addMr(-3);
			sendPackets(new S_Fight(S_Fight.TYPE_JUSTICE_LEVEL1,
					S_Fight.FLAG_OFF));
			break;

		case 2:
			addAc(4);
			addMr(-6);
			sendPackets(new S_Fight(S_Fight.TYPE_JUSTICE_LEVEL2,
					S_Fight.FLAG_OFF));
			break;

		case 3:
			addAc(6);
			addMr(-9);
			sendPackets(new S_Fight(S_Fight.TYPE_JUSTICE_LEVEL3,
					S_Fight.FLAG_OFF));
			break;

		case -1:
			addDmgup(-1);
			addBowDmgup(-1);
			addSp(-1);
			sendPackets(new S_Fight(S_Fight.TYPE_EVIL_LEVEL1, S_Fight.FLAG_OFF));
			break;

		case -2:
			addDmgup(-3);
			addBowDmgup(-3);
			addSp(-2);
			sendPackets(new S_Fight(S_Fight.TYPE_EVIL_LEVEL2, S_Fight.FLAG_OFF));
			break;

		case -3:
			addDmgup(-5);
			addBowDmgup(-5);
			addSp(-3);
			sendPackets(new S_Fight(S_Fight.TYPE_EVIL_LEVEL3, S_Fight.FLAG_OFF));
			break;
		}

		// TODO 增加新的戰鬥特化狀態
		switch (newType) {
		case 1:
			addAc(-2);
			addMr(3);
			sendPackets(new S_Fight(S_Fight.TYPE_JUSTICE_LEVEL1,
					S_Fight.FLAG_ON));
			break;

		case 2:
			addAc(-4);
			addMr(6);
			sendPackets(new S_Fight(S_Fight.TYPE_JUSTICE_LEVEL2,
					S_Fight.FLAG_ON));
			break;

		case 3:
			addAc(-6);
			addMr(9);
			sendPackets(new S_Fight(S_Fight.TYPE_JUSTICE_LEVEL3,
					S_Fight.FLAG_ON));
			break;

		case -1:
			addDmgup(1);
			addBowDmgup(1);
			addSp(1);
			sendPackets(new S_Fight(S_Fight.TYPE_EVIL_LEVEL1, S_Fight.FLAG_ON));
			break;

		case -2:
			addDmgup(3);
			addBowDmgup(3);
			addSp(2);
			sendPackets(new S_Fight(S_Fight.TYPE_EVIL_LEVEL2, S_Fight.FLAG_ON));
			break;

		case -3:
			addDmgup(5);
			addBowDmgup(5);
			addSp(3);
			sendPackets(new S_Fight(S_Fight.TYPE_EVIL_LEVEL3, S_Fight.FLAG_ON));
			break;
		}
	}

	// TODO 確認是否屬於新手, 並設定相關狀態
	public void checkNoviceType() {
		// TODO 判斷是否啟動新手保護系統(遭遇的守護)
		if (!Config.NOVICE_PROTECTION_IS_ACTIVE) {
			return;
		}

		// TODO 判斷目前等級是否已超過新手階段
		if (getLevel() > Config.NOVICE_MAX_LEVEL) {
			// TODO 判斷之前是否具有新手保護狀態
			if (hasSkillEffect(L1SkillId.STATUS_NOVICE)) {
				// TODO 移除新手保護狀態
				removeSkillEffect(L1SkillId.STATUS_NOVICE);
				// TODO 關閉遭遇的守護圖示
				sendPackets(new S_Fight(S_Fight.TYPE_ENCOUNTER,
						S_Fight.FLAG_OFF));
			}
		} else {
			// TODO 判斷是否未具有新手保護狀態
			if (!hasSkillEffect(L1SkillId.STATUS_NOVICE)) {
				// TODO 增加新手保護狀態
				setSkillEffect(L1SkillId.STATUS_NOVICE, 0);

				// TODO 開啟遭遇的守護圖示
				sendPackets(new S_Fight(S_Fight.TYPE_ENCOUNTER, S_Fight.FLAG_ON));
			}
		}
	}

	// TODO 戰鬥特化系統

	// TODO 三段加速
	private int _thirdSpeed;
	private double _move_speed = 1, _attack_speed = 1;

	public void setThirdSpeed(final int i) {
		_thirdSpeed = i;
		switch (i) {
		case 0:
			_attack_speed =1;
			_move_speed = 1;
			break;
		case 1:// opqlo 3段加速
			_move_speed = 0.907;// (331) 193%
			_attack_speed = 0.93;
			break;
		case 2:// oplqo 4段加速
			_move_speed = 0.49;// (241) 265%
			_attack_speed = 0.527;
			break;
		case 3:// oplqo 4.5段加速
			_move_speed = 0.453;// (221) 289%
			_attack_speed = 0.467;
			break;
		case 4:// oplqo 5段加速
			_move_speed = 0.45;// (161) 397%
			_attack_speed = 0.482;
			break;
		}
	}

	public int isThirdSpeed() {
		return _thirdSpeed;
		// TODO 三段加速
	}

	public double getMoveSpeedRate() {
		return _move_speed;
	}

	public double getAttackSpeedRate() {
		return _attack_speed;
	}

	/**/
	/**
	 * 閃避率 +
	 * 
	 * @author by yajackk2001
	 */
	private byte _dodge = 0;

	@Override
	public byte getDodge() {
		return _dodge;
	}

	@Override
	public void addDodge(final byte i) {
		_dodge += i;
		_dodge = (byte) Math.min(_dodge, 10);
		_dodge = (byte) Math.max(_dodge, 0);
	}

	/**
	 * 閃避率 +
	 * 
	 * @author by yajackk2001
	 */

	/**
	 * 閃避率 -
	 * 
	 * @author by yajackk2001
	 */
	private byte _nDodge = 0;

	@Override
	public byte getNdodge() {
		return _nDodge;
	}

	@Override
	public void addNdodge(final byte i) {
		_nDodge += i;
		_nDodge = (byte) Math.min(_nDodge, 10);
		_nDodge = (byte) Math.max(_nDodge, 0);
	}

	/**
	 * 閃避率 -
	 * 
	 * @author by yajackk2001
	 */

	/**
	 * 生存吶喊時間
	 * 
	 * @return
	 */
	private long _h_time;// TODO 生存吶喊時間

	/**
	 * 生存吶喊時間
	 * 
	 * @return
	 */
	public long get_h_time() {
		return _h_time;
	}

	/**
	 * 生存吶喊時間
	 * 
	 * @param h_time
	 */
	public void set_h_time(final long h_time) {
		_h_time = h_time;
	}

	// opqlo 改名卡
	private boolean _changeName = false;

	public boolean isChangeName() {
		return _changeName;
	}

	public void setChangeName(final int b) {
		if (b == 1) {
			_changeName = true;
		} else {
			_changeName = false;
		}
	}

	public boolean _OPQLO_Test = false;
	// 增加掛機判斷問答系統ADD
	private int _CheckCount;
	private int _AICount;
	private int _super;
	public byte _qai = 1;

	public int getSuper() {
		return _super;
	}

	public int getCheckCount() {
		return _CheckCount;
	}

	public void setCheckCount(final int i) {
		_CheckCount = i;
	}

	public void addCheckCount() {
		_CheckCount++;
	}

	public void setSuper(final int i) {
		_super = i;
	}

	public void setAICount(final int i) {
		_AICount = i;
	}

	public int getAICount() {
		return _AICount;
	}

	// 增加掛機判斷問答系統END
	// opqlo 竊聽頻道開關
	private boolean OVERHEARD;// GM偷聽密語頻道開關
	private boolean OVERHEARD0;// GM偷聽一般頻道開關
	private boolean OVERHEARD4;// GM偷聽血盟頻道開關
	private boolean OVERHEARD11;// GM偷聽組隊頻道開關
	private boolean OVERHEARD13;// GM偷聽聯盟頻道開關
	private boolean OVERHEARDXX;// GM偷聽聯盟頻道開關
	private boolean ALLCLOSE = true;// 關閉全部竊聽

	public void setOverHead(final boolean i) {
		OVERHEARD = i;
	}

	public void setOverHead0(final boolean i) {
		OVERHEARD0 = i;
	}

	public void setOverHead4(final boolean i) {
		OVERHEARD4 = i;
	}

	public void setOverHead11(final boolean i) {
		OVERHEARD11 = i;
	}

	public void setOverHead13(final boolean i) {
		OVERHEARD13 = i;
	}

	public void setOverHeadXX(final boolean i) {
		OVERHEARDXX = i;
	}

	public boolean isOverHeadXX() {
		return OVERHEARDXX;
	}

	public boolean isOverHead() {
		return OVERHEARD;
	}

	public boolean isOverHead0() {
		return OVERHEARD0;
	}

	public boolean isOverHead4() {
		return OVERHEARD4;
	}

	public boolean isOverHead11() {
		return OVERHEARD11;
	}

	public boolean isOverHead13() {
		return OVERHEARD13;
	}

	public boolean isAllClose() {
		return ALLCLOSE;
	}

	public void allclose() {
		final boolean i = false;
		OVERHEARD = i;
		OVERHEARD0 = i;
		OVERHEARD4 = i;
		OVERHEARD11 = i;
		OVERHEARD13 = i;
		OVERHEARDXX = i;
		ALLCLOSE = true;
	}

	public void allopen() {
		final boolean i = true;
		OVERHEARD = i;
		OVERHEARD0 = i;
		OVERHEARD4 = i;
		OVERHEARD11 = i;
		OVERHEARD13 = i;
		OVERHEARDXX = i;
		ALLCLOSE = false;
	}

	public boolean isWindShackle() { // 風之枷鎖 攻速 / 2
		return hasSkillEffect(WIND_SHACKLE);
	}

	public boolean isRibrave() { // 生命之樹果實 移速 * 1.15
		return hasSkillEffect(STATUS_RIBRAVE);
	}

	// opqlo 套裝攻擊力加成
	private int[] _ArmorType = { 0, 0, 0, 0, 0 };

	public void setArmorType(final int i) {
		for (int s = 0; s < _ArmorType.length; s++) {
			if (_ArmorType[s] == 0) {
				_ArmorType[s] = i;
				break;
			}
		}
	}

	public void stopArmorType(final int i) {
		for (int s = 0; s < _ArmorType.length; s++) {
			if (_ArmorType[s] == i) {
				_ArmorType[s] = 0;
				break;
			}
		}
	}

	public int[] getArmorType() {
		return _ArmorType;
	}

	// opqlo 套裝攻擊力加成

	// opqlo 關閉特效測試
	private boolean _isEffectOff = false;

	public void setIsEffectOff() {
		if (_isEffectOff == false) {
			_isEffectOff = true;
			sendPackets(new S_SystemMessage("關閉大部分特效"));
		} else {
			sendPackets(new S_SystemMessage("開啟大部分特效"));
			_isEffectOff = false;
		}
	}

	public boolean getIsEffectOff() {
		return _isEffectOff;
	}

	// opqlo 關閉特效測試

	/*
	 * // opqlo灼熱內衣效果 private BulajiaMagic BulajiaMagic; // 記得先 import
	 * l1j.william.SustainEffect;
	 * 
	 * public void BulajiaMagic(final L1PcInstance pc ) {
	 * 
	 * int _Interval =5000; // 間隔時間 BulajiaMagic = new BulajiaMagic(pc);
	 * _regenTimer.scheduleAtFixedRate(BulajiaMagic,_Interval, _Interval);
	 * 
	 * }
	 * 
	 * public void stopBulajiaMagic() { BulajiaMagic.cancel(); BulajiaMagic =
	 * null;
	 * 
	 * }
	 * 
	 * //opqlo 道具天數刪除系統(計時器) private ItemTimeDelete _ItemTimeDelete;
	 * 
	 * public void timecheak(final L1ItemInstance item, int delaytime){
	 * delaytime *=1000; _ItemTimeDelete = new ItemTimeDelete(this,item); final
	 * Timer _regenTimer = new Timer();
	 * _regenTimer.scheduleAtFixedRate(_ItemTimeDelete,delaytime, delaytime); }
	 * public void stopItemTimeCheak(){ _ItemTimeDelete.cancel();
	 * _ItemTimeDelete=null; }
	 */
	/** opqlo 獎勵積分系統紀錄 */
	public int[] PointId = { 0, 0, 0 };
	public int[] PointCount = { 0, 0, 0 };

	private double isExpup = 1;

	public void addExpUp(final double rate) {
		isExpup += rate;
	}

	public double getExpUp() {
		return isExpup + _CastleExpRate;
	}

	public boolean isVIP;
	public double getExpRate = 1;
	private int _X;
	private int _Y;
	private short _MAP;

	public void setMapXY(final int x, final int y, final short map) {
		_X = x;
		_Y = y;
		_MAP = map;
	}

	public void getMapXY() {
		L1Teleport.teleportByMagic(this, _X, _Y, _MAP, 5, false);
	}

	public boolean AttackX3 = false;// opqlo 三連斬
	public int AttackX3_Chance = 0;

	/** opqlo 是否可以移動、攻擊、使用道具 */
	public boolean Canuse() {
		return isGhost() || isDead() || isTeleport() || getSuper() > 0 || isParalyzed() || isSleeped();
	}

	public boolean inQuestGame = false;
	// 寄賣系統清單版本號碼
	public int ShopListVersion;

	/**
	 * 發送單體封包 與指定範圍發送封包(範圍10)
	 * 
	 * @param packet
	 *            封包
	 */
	public void sendPacketsX10(final ServerBasePacket packet) {
		if (this._out == null) {
			return;
		}

		try {
			// 自己
			this._out.encrypt(packet);
			if (!this.isGmInvis() && !this.isInvisble()) {
				this.broadcastPacketX10(packet);
			}

		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
			this.close();
		}
	}

	/**
	 * 發送單體封包 與可見範圍發送封包
	 * 
	 * @param packet
	 *            封包
	 */
	public void sendPacketsAll(final ServerBasePacket packet) {
		if (this._out == null) {
			return;
		}

		try {
			// 自己
			this._out.encrypt(packet);
			if (!this.isGmInvis() && !this.isInvisble()) {
				this.broadcastPacketAll(packet);
			}

		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
			this.close();
		}
	}

	/**
	 * 發送單體封包 與指定範圍發送封包(範圍8)
	 * 
	 * @param packet
	 *            封包
	 */
	public void sendPacketsX8(final ServerBasePacket packet) {
		if (this._out == null) {
			return;
		}

		try {
			// 自己
			this._out.encrypt(packet);
			if (!this.isGmInvis() && !this.isInvisble()) {
				this.broadcastPacketX8(packet);
			}

		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
			this.close();
		}
	}

	/**
	 * 發送武器特效封包 與指定範圍發送封包(範圍8)
	 * 
	 * @param packet
	 *            封包
	 */
	public void sendWeaponEffectPackets(final ServerBasePacket packet , final L1Character traget) {
		if (this._out == null || traget == null) {
			return;
		}

		try {
			// 自己
			this._out.encrypt(packet);
			if (!this.isGmInvis() && !this.isInvisble()) {
				this.broadcastWeaponEffectPacket(packet , traget);
			}

		} catch (final Exception e) {
			_log.log(Level.SEVERE, e.getLocalizedMessage(), e);
			this.close();
		}
	}
	/**
	 * 該物件指定範圍封包發送(範圍8)
	 * @param packet 封包
	 */
	public void broadcastWeaponEffectPacket(final ServerBasePacket packet , final L1Character traget) {
		try {
			for (final L1PcInstance pc : L1World.getInstance().getVisiblePlayer(this, 8)) {
				if(!pc.isTeleport()){
					if(pc.getConfig().isWeaponEffect() || pc == traget){
						pc.sendPackets(packet);
					}
				}
			}

		} catch (final Exception e) {
			_log.log(Level.WARNING,e.getLocalizedMessage(), e);
		}
	}

	private Timestamp _deleteTime; // キャラクター削除までの時間

	public Timestamp getDeleteTime() {
		return _deleteTime;
	}

	public void setDeleteTime(final Timestamp time) {
		_deleteTime = time;
	}

	private double _TRIPLE_ARROW;

	/** 設定三重矢傷害加成 */
	public void setTRIPLE_ARROW(final double d) {
		_TRIPLE_ARROW += d;
	}

	/** 取得三重矢傷害加成 */
	public double getTRIPLE_ARROW() {

		if (_TRIPLE_ARROW <= 0) {
			return 1;
		}
		return _TRIPLE_ARROW;
	}

	// 暈眩機率增加
	private int _Stundice = 0;
	private int _trueStundice = 0;

	/** 取得 増暈 */
	public int getStunDice() {
		return (_Stundice);
		// 　TODO　　昏迷耐性増加
	}

	/** 增加 增暈 */
	public void addStunDice(final int i) {
		_trueStundice += i;
		if (_trueStundice > 127) {
			_Stundice = 127;
		} else if (_trueStundice < -128) {
			_Stundice = -128;
		} else {
			_Stundice = _trueStundice;
		}
	}

	// 石化機率增加
	private int _Stonedice = 0;
	private int _trueStonedice = 0;

	public int getStoneDice() {
		return (_Stonedice);
		// 　TODO マジックドール効果　石化耐性増加
	}

	public void addStoneDice(final int i) {
		_trueStonedice += i;
		if (_trueStonedice > 127) {
			_Stonedice = 127;
		} else if (_trueStonedice < -128) {
			_Stonedice = -128;
		} else {
			_Stonedice = _trueStonedice;
		}
	}

	// 睡眠增加機率
	private int _Sleepdice = 0;
	private int _trueSleepdice = 0;

	public int getSleepDice() {
		return (_Sleepdice);
		// 　TODO マジックドール効果　睡眠耐性増加
	}

	public void addSleepDice(final int i) {
		_trueSleepdice += i;
		if (_trueSleepdice > 127) {
			_Sleepdice = 127;
		} else if (_trueSleepdice < -128) {
			_Sleepdice = -128;
		} else {
			_Sleepdice = _trueSleepdice;
		}
	}

	// 增加凍結機率
	private int _Freezedice = 0;
	private int _trueFreezedice = 0;

	public int getFreezeDice() {
		return (_Freezedice);
		// TODO　マジックドール效果　凍結耐性
	}

	public void addFreezeDice(final int i) {
		_trueFreezedice += i;
		if (_trueFreezedice > 127) {
			_Freezedice = 127;
		} else if (_trueFreezedice < -128) {
			_Freezedice = -128;
		} else {
			_Freezedice = _trueFreezedice;
		}
	}

	// 支撐機率增加
	private int _Sustaindice = 0;
	private int _trueSustaindice = 0;

	public int getSustainDice() {
		return (_Sustaindice);
		// TODO マジックドール效果 　支撐耐性
	}

	// 支撐耐性
	public void addSustainDice(final int i) {
		_trueSustaindice += i;
		if (_trueSustaindice > 127) {
			_Sustaindice = 127;
		} else if (_trueSustaindice < -128) {
			_Sustaindice = -128;
		} else {
			_Sustaindice = _trueSustaindice;
		}
	}

	// 增加暗黑機率
	private int _Blinddice = 0;
	private int _trueBlinddice = 0;

	public int getBlindDice() {
		return (_Blinddice);
		// TODO マジックドール效果 　暗闇耐性
	}

	public void addBlindDice(final int i) {
		_trueBlinddice += i;
		if (_trueBlinddice > 127) {
			_Blinddice = 127;
		} else if (_trueBlinddice < -128) {
			_Blinddice = -128;
		} else {
			_Blinddice = _trueBlinddice;
		}
	}

	private int _magicDmg;

	public void addMagicDmgModfier(final int i) {
		_magicDmg += i;
	}

	public int getMagicDmgModfier() {
		return _magicDmg + _CastleMagicModDmg;
	}

	/** opqlo 掉寶率 */

	private double _droprate;

	public void addDroprate(final double i) {
		_droprate += i;
	}

	public double getDroprate() {
		return _droprate + _CastleDropRate;

	}

	/** opqlo 金幣率 */

	private double _金幣率;

	public void add金幣率(final double i) {
		_金幣率 += i;
	}

	public double get金幣率() {
		return _金幣率 + _CastleDropRate;
	}

	private StringBuilder 出售商品價格;

	public StringBuilder get出售商品價格() {
		return 出售商品價格;
	}

	public void set出售商品價格(final String s) {
		if (出售商品價格 == null) {
			出售商品價格 = new StringBuilder();
		}
		if (出售商品價格.length() == 0 && s.equalsIgnoreCase("0")) {
			return;
		}
		if (出售商品價格.length() <= 5) {
			出售商品價格.append(s);
		}
	}

	public void 清除出售商品價格() {
		出售商品價格.delete(0, 出售商品價格.length());
	}

	private ArrayList<L1ItemInstance> 出售商品清單;

	public void Set出售商品清單(final L1ItemInstance item) {
		if (出售商品清單 == null) {
			出售商品清單 = new ArrayList<L1ItemInstance>();
		}
		出售商品清單.add(item);
	}

	public ArrayList<L1ItemInstance> get出售商品清單() {
		return 出售商品清單;
	}

	private int _lastSp;

	public boolean checkLastSP() {
		if (_lastSp == getSp()) {
			return false;
		} else {
			_lastSp = getSp();
			return true;
		}
	}

	/** 城堡技能 **/
	/** 狂暴打擊 */
	public int _CastleweaponSkillDmg;
	public int _CastleMagicModDmg;
	/** 鋼鐵防禦 */
	public int _CastleExtraDef;
	public int _CastleDmgReduction;
	/** 賞金獵人 */
	public double _CastleDropRate;
	/** 狩獵專長 */
	public double _CastleExpRate;
	/** 城堡技能 **/

	private HashMap<Integer, L1ItemInstance> _armor = new HashMap<Integer, L1ItemInstance>();// 裝備列表

	public void WearArmor(final L1ItemInstance armor, final int armorType) {// 穿裝備
		if (armor.getItem().getType2() != 2) {
			return;
		}
		if (_armor.get(armorType) != null) {
			_armor.remove(armorType);
		}
		_armor.put(new Integer(armorType), armor);
	}

	public void StripArmor(final int armorType) {// 脫裝備
		if (_armor.get(armorType) != null) {
			_armor.remove(armorType);
		}
	}

	public L1ItemInstance getArmor(final int armorType) {// 取得裝備Instance
		return _armor.get(armorType);
	}

	public int _coverType = -1;

	/** opqlo 防穿牆 */

	public void addMoveErrorCount(L1Location loc) {

		String msg = "IP:(" + this.getNetConnection().getIp().toString()
				+ ")玩家名稱: " + this.getName() + "	地圖編號: " + loc.getMapId()
				+ "	X: " + loc.getX() + "	Y: " + loc.getY() + "	創造卡點青蛙。";
		各項記錄輸出.LogSave(24, msg);
		// _log.warning(msg);

	}

	/** opqlo 防穿牆 */

	public StringBuilder msg;

	public long Timetime;

	public boolean _isX3;

	private String[] _刮刮樂號碼;

	public void set刮刮樂號碼(String[] data) {
		_刮刮樂號碼 = data;
	}

	public String[] get刮刮樂號碼() {
		return _刮刮樂號碼;
	}

	private int _中獎金額;

	public int get中獎金額() {
		return _中獎金額;
	}

	public void add中獎金額(final int i) {
		_中獎金額 += i;
	}

	private int _中獎次數;

	public int get中獎次數() {
		return _中獎次數;
	}

	public void add中獎次數(final int i) {
		_中獎次數 += i;
	}

	public boolean 進行中;

	public void login刮刮樂(String s) {
		if (s == null) {
			return;
		}
		final StringTokenizer st = new StringTokenizer(s, ",");
		final int iSize = st.countTokens();

		final String[] iReturn = new String[iSize];
		for (int i = 0; i < iSize; i++) {
			iReturn[i] = st.nextToken();
			if (i == 9) {
				_中獎次數 = 刮刮樂.getInstance().get中獎次數(iReturn[i]);
			}
		}
		_刮刮樂號碼 = iReturn;
		進行中 = true;
	}

	public String logout刮刮樂() {
		if (_刮刮樂號碼 == null) {
			return null;
		}
		StringBuffer log = new StringBuffer();
		for (int i = 0; i < 10; i++) {
			log.append(_刮刮樂號碼[i]);
			if (log.length() != 19) {
				log.append(",");
			}
		}
		return log.toString();
	}

	/** 屬性增傷 */
	private HashMap<Integer, Double> _attrDmg;

	public void addAttrDmg(final int attr, double value) {

		if (_attrDmg == null) {
			_attrDmg = new HashMap<Integer, Double>();
		}
		if (_attrDmg.containsKey(attr)) {
			Double vv = _attrDmg.get(attr);
			if(vv == null){vv = 0.0;}
			value += vv;
			_attrDmg.remove(attr);
		}
		_attrDmg.put(attr, value);
	}

	public double getAttrDmg(final int attr) {
		if (_attrDmg == null) {
			return 0;
		}
		if (_attrDmg.get(attr) == null) {
			return 0;
		}

		return _attrDmg.get(attr);
	}

	private HashMap<Integer, Double> _ethnicity;// 種族相剋

	/** 0=普通、1=不死系、2=惡魔系、3=BOSS系、4=亡靈系、5=狼人系、6=龍系 */
	public void addEthncityDmg(final int type, double value) {

		if (_ethnicity == null) {
			_ethnicity = new HashMap<Integer, Double>();
		}

		if (_ethnicity.containsKey(type)) {
			Double v = _ethnicity.get(type);
			if(v ==null){
				v = 0.0;
			}
			value += v;
			_ethnicity.remove(type);
		}
		_ethnicity.put(type, value);
	}

	/** 0=普通、1=不死系、2=惡魔系、3=BOSS系、4=亡靈系、5=狼人系、6=龍系 */
	public double getEthncityDmg(final int type) {
		if (_ethnicity == null) {
			return 0;
		}
		if (_ethnicity.get(type) == null) {
			return 0;
		}
		return _ethnicity.get(type);
	}

	private HashMap<Integer, Double> _attrdef = new HashMap<Integer, Double>();;// 屬性減傷

	/** 風剋水 、 水剋火、 火剋地、地剋風  */
	public void addAttrDef(final int type , final double value){
		switch(type){
		case 1:
			_attrdef.put(8, value);
			break;
		case 2:
			_attrdef.put(4, value);
			break;
		case 4:
			_attrdef.put(2, value);
			break;
		case 5:
			_attrdef.put(6, value);
			break;
		case 6:
			_attrdef.put(5, value);
			break;
		case 8:
			_attrdef.put(1, value);
			break;
		}
	}

	public double getAttrDef(final int type){
		if(!_attrdef.containsKey(type)){
			return 0;
		}
		return _attrdef.get(type);
	}


	public long 大喊延遲, 公頻延遲, 買賣延遲;

	private int _registStone = 0;// 石化耐性
	private int _registSleep = 0;// 睡眠耐性
	private int _registFreeze = 0;// 凍結耐性

	private int _registSustain = 0;// 支撐耐性
	private int _registBlind = 0;// 暗闇耐性


	public void setRegistBlind(final int i) {
		this._registBlind += i;
	}

	public void setRegistFreeze(final int i) {
		this._registFreeze += i;
	}

	public void setRegistSleep(final int i) {
		this._registSleep += i;
	}

	public void setRegistStone(final int i) {
		this._registStone += i;
	}

	public void setRegistSustain(final int i) {
		this._registSustain += i;
	}
	

	public int getRegistBlind() {
		return this._registBlind;
	}

	public int getRegistFreeze() {
		return this._registFreeze;
	}

	public int getRegistSleep() {
		return this._registSleep;
	}

	public int getRegistStone() {
		return this._registStone;
	}

	public int getRegistSustain() {
		return this._registSustain;
	}

	private List<L1ChatTemp> _Chatlist= new ArrayList<L1ChatTemp>();

	public boolean checkGlobal(final byte[] chattext){
		try{
			int total = 0;
			for(final byte b : chattext){
				total +=b;
			}
			if(this._Chatlist.isEmpty()){
				this._Chatlist.add(new L1ChatTemp(chattext , total));
				return true;
			}
			if(this._Chatlist !=null){
				final Iterator<L1ChatTemp> list =this._Chatlist.iterator();
				L1ChatTemp temp;
				List<L1ChatTemp> removeList = null;
				boolean re = false;
				while(list.hasNext()){
					temp =list.next();
					//for(L1ChatTemp temp : _Chatlist){
					if(!temp.checkChat(chattext , total)){
						re = true;
					}else if(temp.isActlive()){
						if(removeList == null){
							removeList = new ArrayList<L1ChatTemp>();
						}
						removeList.add(temp);
					}
				}
				if(removeList!=null && !removeList.isEmpty()){
					this._Chatlist.removeAll(removeList);
					removeList.clear();removeList = null;
				}
				if(re){
					this.sendPackets(new S_SystemMessage("請勿重複發話。"));
					return false;
				}
				this._Chatlist.add(new L1ChatTemp(chattext , total));
			}
			return true;
		}catch(Exception e){
			_log.log(Level.SEVERE, e.getLocalizedMessage() , e);
		}
		return false;
	}
	private int _extraHp ,_extraMp;
	public int getExtraHp(){
		return _extraHp;
	}
	public int getExtraMp(){
		return _extraMp;
	}
	public void setExtraHp(final int i){
		_extraHp = i;
	}
	public void setExtraMp(final int i){
		_extraMp = i;
	}
	/**opqlo 傳卷結界保護(3秒)*/
	public boolean TelePortSetSkill = false;
	//final Iterator<L1PcInstance> itr = L1World.getInstance().getAllPlayers().iterator();
	private ArrayList<L1PcInstance> _list;
	private HashMap<Integer , ArrayList<L1PcInstance>>_onlinemap;
	public int _ListPage =0;
	public void setAllPcList(Iterator<L1PcInstance> itr){
		if(itr == null){
			return;
		}
		int pc_count = 0;
		if(_list == null){
			_list = new ArrayList<L1PcInstance>();
		}else{
			_list.clear();
		}
		if(_onlinemap == null){
			_onlinemap = new HashMap<Integer , ArrayList<L1PcInstance>>();
		}else{
			_onlinemap.clear();
		}
		int page = 1;
		_ListPage =0;
		while (itr.hasNext()) {
			final L1PcInstance pc = itr.next();
			_list.add(pc);
			pc_count ++;
			if(pc_count ==100){
				final ArrayList<L1PcInstance> list = new ArrayList<L1PcInstance>();
				list.addAll(_list);
				_onlinemap.put(page, list);
				page++;
				_list.clear();
				pc_count =0;
			}
		}
		if(!_list.isEmpty()){
			final ArrayList<L1PcInstance> list = new ArrayList<L1PcInstance>();
			list.addAll(_list);
			_onlinemap.put(page, list);
			_list.clear();
		}
	}

	public ArrayList<L1PcInstance> getAllPcList(final boolean nextpage){
		if(nextpage){
			_ListPage++;
		}else{
			_ListPage--;
		}
		return _onlinemap.get(_ListPage);
	}
	public boolean haveNextPage(){
		return _onlinemap.containsKey(_ListPage+1);
	}

	private GameConfig _config;

	public GameConfig getConfig(){
		if(_config == null){
			_config = GameConfigReading.get().getConfig(getId());
		}
		return _config;
	}
	private HashMap<Integer , Integer>_bailmentList;
	private int _bailmentpage ;

	public void setBailMentList(final HashMap<Integer , Integer>bailmentList){
		if(_bailmentList !=null){
			_bailmentList.clear();
		}
		_bailmentpage = 1;
		_bailmentList = bailmentList;
	}
	public int getBailMentObjid(final int orderid){
		if(_bailmentList == null){
			return 0;
		}
		if(_bailmentList.containsKey(orderid)){
			return _bailmentList.get(orderid);
		}
		return 0;
	}
	public int getBailMentPage(){
		return _bailmentpage;
	}

	public void setBailMentPage(boolean isadd){
		if(isadd){
			_bailmentpage++;
		}else{
			_bailmentpage--;
		}
	}
	private int _bailmentId;
	public void setBailMentId(final int objid){
		_bailmentId = objid;
	}
	public int getBailMentId(){
		return _bailmentId;
	}

	private long _check_error_time;
	private byte _move_error_amount;
	public void addMoveError(){
		final long nowTime = System.currentTimeMillis();
		if(nowTime - _check_error_time <= 60000){
			_move_error_amount ++;
			if(_move_error_amount >10){
				sendPackets(new S_ServerMessage(945)); // 違法プログラムが見つかったので、終了します。
				getNetConnection().close();// 中斷
				_log.info(String.format("加速器檢測通知%s被強制中斷連線。", this.getName()));
				return;
			}
		}else{
			_move_error_amount =0;
		}
		_check_error_time = nowTime;
	}

	/**是否是禁止瞬移的狀態(true=不可瞬移 : false=可以瞬移 )GM除外**/
	public boolean isCantTeleport(){
		if(this.isGm()){
			return false;
		}
		return getMapId() == 1813 ||  this.isInHell() || this.isDead();
	}

	public int _inFighting ;
	public int _DECOMPSET_ITEMID ;

//	private long _checkTime , _delayTime;
//	private int _checkCount;
//	private static int AI_TIME = 600;
//	public void checkAI(){
//		if(_checkCount>=20){
//			this.sendPackets(new S_ServerMessage(945));
//			try {
//				Thread.sleep(1000);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//			this.getNetConnection().close();
//		}else{
//			if(GameServer.getInstance().checkMapId(this.getMapId())){
//				final long nowTime = System.currentTimeMillis() , checkTime = nowTime - _checkTime;
//				if(checkTime <=4500){
//					_delayTime = checkTime;
//					_checkTime = nowTime;
//					return;
//				}
//				if(checkTime <= (_delayTime+AI_TIME)
//						&& checkTime >= (_delayTime-AI_TIME)){
//					_checkCount++;
//				}else{
//					_checkCount = 0;
//				}
//				_delayTime = checkTime;
//				_checkTime = nowTime;
//			}else if(_checkCount != 0){
//				_checkCount = 0;
//			}
//		}
//	}

	private StringBuilder newAccount;

	public StringBuilder getnewAccount(){
		if(newAccount == null){
			newAccount = new StringBuilder().append(this.getAccountName());
		}
		return newAccount;
	}
	
	private L1DollList _dollList ;
	public L1DollList getDollList(){
		return _dollList;
	}
	
	
	private String[] _chatLog = {"" , ""};
	/**重複的說話不要記錄*/
	public boolean checkLog(final String chat){
		boolean norepeat = true;
		for(int i=0; i<_chatLog.length; i++){
			norepeat = chat.equals(_chatLog[i])==false; //是否沒重複
			if(norepeat == false){//如果有重複
				break;
			}
		}
		if(norepeat){
			_chatLog[0] = _chatLog[1];
			_chatLog[1] = chat;
		}
		return norepeat;
	}
	
	public L1ItemInstance EACHANTING_ITEM;
	
	public int BET_RATE =10;
	public String HTMLID_TEMP;
	
	
	private RobotTemp _robotTemp;
	
	public void setRobotTemp(RobotTemp temp){
		_robotTemp = temp;
	}
	public RobotTemp getRobotTemp(){
		return _robotTemp;
	}
}
